Skip to content

Commit fa281b2

Browse files
committed
feat: add OAuth2 client facebook example
1 parent 7301dd7 commit fa281b2

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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

Comments
 (0)