|
| 1 | +# OAuth2 clients |
| 2 | + |
| 3 | +Fastfony provides a simple way to implement OAuth2 clients in your Symfony application. This is useful for integrating with third-party services that require OAuth2 authentication and for offer login with third-party services. |
| 4 | + |
| 5 | +## Usage |
| 6 | + |
| 7 | +Fastfony use [knpuniversity/oauth2-client-bundle](https://github.com/knpuniversity/oauth2-client-bundle) to manage OAuth2 clients. It is already installed and configured in Fastfony, so you can use it directly in your application. |
| 8 | + |
| 9 | +Two providers from [League](https://github.com/thephpleague) are already configured in Fastfony: [Google](https://github.com/thephpleague/oauth2-google) and [Github](https://github.com/thephpleague/oauth2-github), but you can add more providers as needed. |
| 10 | + |
| 11 | +In the admin interface, on settings screen, you can manage Google and Github connection : just provide your OAuth2 credentials (client ID and secret) to enable the connection. |
| 12 | + |
| 13 | +## Adding a new OAuth2 client |
| 14 | + |
| 15 | +You can add a new [OAuth2 client library](https://github.com/knpuniversity/oauth2-client-bundle?tab=readme-ov-file#step-1-download-the-client-library) for support new third-party services. |
| 16 | + |
| 17 | +For Facebook by example, you can add them by following these steps: |
| 18 | + |
| 19 | +```bash |
| 20 | +composer require league/oauth2-facebook |
| 21 | +``` |
| 22 | + |
| 23 | +Create an app on [Facebook for developers](https://developers.facebook.com/) and get your client ID and secret. |
| 24 | + |
| 25 | +Indicate the valid OAuth redirect URL: (your domain name followed by `/connect/facebook/check`, we will create this route later in Fastfony). |
| 26 | + |
| 27 | +Then, add the following configuration in `config/packages/knpu_oauth2_client.yaml`: |
| 28 | + |
| 29 | +```yaml |
| 30 | +knpu_oauth2_client: |
| 31 | + clients: |
| 32 | + facebook: |
| 33 | + type: facebook |
| 34 | + client_id: '%env(FACEBOOK_CLIENT_ID)%' |
| 35 | + client_secret: '%env(FACEBOOK_CLIENT_SECRET)%' |
| 36 | + redirect_route: connect_facebook_check |
| 37 | + graph_api_version: v2.12 |
| 38 | +``` |
| 39 | +
|
| 40 | +Finally, add the environment variables in your `.env` file: |
| 41 | + |
| 42 | +```dotenv |
| 43 | +FACEBOOK_CLIENT_ID=your_facebook_client_id |
| 44 | +FACEBOOK_CLIENT_SECRET=your_facebook_client_secret |
| 45 | +``` |
| 46 | + |
| 47 | +(you can also create Parameter in the admin interface, and use Parameter entity). |
| 48 | + |
| 49 | +Create two controllers to handle the connection and the check: |
| 50 | + |
| 51 | +```php |
| 52 | +# src/Controller/Security/OAuthClient/Facebook/Check.php |
| 53 | +<?php |
| 54 | +
|
| 55 | +declare(strict_types=1); |
| 56 | +
|
| 57 | +namespace App\Controller\Security\OAuthClient\Facebook; |
| 58 | +
|
| 59 | +use App\Controller\Security\OAuthClient\AbstractCheck; |
| 60 | +use Symfony\Component\Routing\Attribute\Route; |
| 61 | +
|
| 62 | +/** @phpstan-ignore symfony.noClassLevelRoute */ |
| 63 | +#[Route('/connect/facebook/check', name: 'connect_facebook_check')] |
| 64 | +class Check extends AbstractCheck |
| 65 | +{ |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +```php |
| 70 | +# src/Controller/Security/OAuthClient/Facebook/Connect.php |
| 71 | +<?php |
| 72 | +
|
| 73 | +declare(strict_types=1); |
| 74 | +
|
| 75 | +namespace App\Controller\Security\OAuthClient\Facebook; |
| 76 | +
|
| 77 | +use App\Controller\Security\OAuthClient\AbstractConnect; |
| 78 | +use Symfony\Component\HttpFoundation\RedirectResponse; |
| 79 | +use Symfony\Component\Routing\Attribute\Route; |
| 80 | +
|
| 81 | +class Connect extends AbstractConnect |
| 82 | +{ |
| 83 | + #[Route('/connect/github', name: 'connect_facebook', methods: ['GET'])] |
| 84 | + public function __invoke(string $service = 'facebook'): RedirectResponse |
| 85 | + { |
| 86 | + $this->scopes = ['public_profile', 'email']; |
| 87 | +
|
| 88 | + return parent::__invoke($service); |
| 89 | + } |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +Finally, create new authenticator to handle the Facebook OAuth2 client: |
| 94 | + |
| 95 | +```php |
| 96 | +# src/Security/OAuthClient/FacebookAuthenticator.php |
| 97 | +<?php |
| 98 | +
|
| 99 | +declare(strict_types=1); |
| 100 | +
|
| 101 | +namespace App\Security\OAuthClient; |
| 102 | +
|
| 103 | +class FacebookAuthenticator extends AbstractAuthenticator |
| 104 | +{ |
| 105 | + public function getClientName(): string |
| 106 | + { |
| 107 | + return 'facebook'; |
| 108 | + } |
| 109 | +
|
| 110 | + // You can override the AbstractAuthenticator methods to customize the authentication process if needed. |
| 111 | +} |
| 112 | +``` |
| 113 | + |
| 114 | +Add it in your `config/packages/security.yaml`: |
| 115 | + |
| 116 | +```yaml |
| 117 | +security: |
| 118 | + firewalls: |
| 119 | + main: |
| 120 | + # ... |
| 121 | + custom_authenticators: |
| 122 | + # ... |
| 123 | + - App\Security\OAuthClient\FacebookAuthenticator |
| 124 | +``` |
| 125 | + |
| 126 | +And, add `fromFacebook` in UserFactory class to handle the user find or creation from Facebook OAuth2 client: |
| 127 | + |
| 128 | +```php |
| 129 | +# src/Factory/UserFactory.php |
| 130 | +<?php |
| 131 | +# ... |
| 132 | + public function fromFacebook(FacebookUser $facebookUser): User |
| 133 | + { |
| 134 | + $existingUser = $this->userRepository->findOneBy(['email' => $facebookUser->getEmail()]); |
| 135 | + if ($existingUser) { |
| 136 | + return $existingUser; |
| 137 | + } |
| 138 | +
|
| 139 | + return $this->userRepository->create($facebookUser->getEmail()); |
| 140 | + } |
| 141 | +#... |
| 142 | +``` |
| 143 | + |
| 144 | +Now, you can use the Facebook OAuth2 client in your application. |
| 145 | +You can add a link to the connection in your templates: |
| 146 | + |
| 147 | +```twig |
| 148 | +{# templates/security/_oauth_clients.html.twig #} |
| 149 | +
|
| 150 | + {# ... #} |
| 151 | +
|
| 152 | + <a href="{{ path('connect_facebook') }}" class="btn bg-[#1A77F2] text-white border-[#005fd8]" data-turbo="false"> |
| 153 | + <svg aria-label="Facebook logo" width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="white" d="M8 12h5V8c0-6 4-7 11-6v5c-4 0-5 0-5 3v2h5l-1 6h-4v12h-6V18H8z"></path></svg> |
| 154 | + Facebook |
| 155 | + </a> |
| 156 | +
|
| 157 | + {# ... #} |
| 158 | +``` |
| 159 | + |
| 160 | +--- |
| 161 | + |
| 162 | +You can add more OAuth2 clients by following the same steps as above, just change the provider name and the configuration accordingly. |
0 commit comments