SlideShare a Scribd company logo
L o g o w a n i e u ż y t k o w n i k ó w w R E S T A P I n a
m i k r o s e r w i s a c h
G R U PA Q P O N Y B L I X
P O N A D 3 0 0 0 0 0 0 U Ż Y T K O W N I K Ó W M I E S I Ę C Z N I E
J W T
J S O N W e b T o k e n
J s o n W e b T o k e n
JSON Web Token (JWT) is an open standard (RFC 7519) that
defines a compact and self-contained way for securely transmitting
information between parties as a JSON object.
J s o n W e b T o k e n
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3O
DkwIiwibmFtZSI6IkdyemVnb3J6IiwicGhwZXJzIjoyMDE5LCJpYXQiO
jE1MTYyMzkwMjJ9.fDuS4X19nQ9B3c9QWVsbYJqI4ckBXetARlxZp
RXHOOw
J s o n W e b T o k e n
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3O
DkwIiwibmFtZSI6IkdyemVnb3J6IiwicGhwZXJzIjoyMDE5LCJpYXQiO
jE1MTYyMzkwMjJ9.fDuS4X19nQ9B3c9QWVsbYJqI4ckBXetARlxZp
RXHOOw
J s o n W e b T o k e n
J s o n W e b T o k e n
eyJhbGciOiJIUzI1NiIsInR5cCI6
IkpXVCJ9
J s o n W e b T o k e n
eyJhbGciOiJIUzI1NiIsInR5cCI6
IkpXVCJ9
{
"alg": "HS256",
"typ": "JWT"
}
J s o n W e b T o k e n
eyJhbGciOiJIUzI1NiIsInR5cCI6
IkpXVCJ9
eyJzdWIiOiIxMjM0NTY3ODkwI
iwibmFtZSI6IkdyemVnb3J6Iiwi
cGhwZXJzIjoyMDE5LCJpYXQi
OjE1MTYyMzkwMjJ9
{
"alg": "HS256",
"typ": "JWT"
}
J s o n W e b T o k e n
eyJhbGciOiJIUzI1NiIsInR5cCI6
IkpXVCJ9
eyJzdWIiOiIxMjM0NTY3ODkwI
iwibmFtZSI6IkdyemVnb3J6Iiwi
cGhwZXJzIjoyMDE5LCJpYXQi
OjE1MTYyMzkwMjJ9
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "Grzegorz",
"phpers": 2019,
"iat": 1516239022
}
J s o n W e b T o k e n
eyJhbGciOiJIUzI1NiIsInR5cCI6
IkpXVCJ9
eyJzdWIiOiIxMjM0NTY3ODkwI
iwibmFtZSI6IkdyemVnb3J6Iiwi
cGhwZXJzIjoyMDE5LCJpYXQi
OjE1MTYyMzkwMjJ9
fDuS4X19nQ9B3c9QWVsbYJq
I4ckBXetARlxZpRXHOOw
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "Grzegorz",
"phpers": 2019,
"iat": 1516239022
}
J s o n W e b T o k e n
eyJhbGciOiJIUzI1NiIsInR5cCI6
IkpXVCJ9
eyJzdWIiOiIxMjM0NTY3ODkwI
iwibmFtZSI6IkdyemVnb3J6Iiwi
cGhwZXJzIjoyMDE5LCJpYXQi
OjE1MTYyMzkwMjJ9
fDuS4X19nQ9B3c9QWVsbYJq
I4ckBXetARlxZpRXHOOw
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "Grzegorz",
"phpers": 2019,
"iat": 1516239022
}
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
PHPers2019
)
H E A D E R
T y p e A l g o r i t h m
HS256
HS384
HS512
RS256
RS384
RS512
ES256
ES384
ES512
PS256
PS384
PS512
J W T
PAY L O A D
R e g i s t e r e d C l a i m N a m e s
PAY L O A D
Issuer (iss)
Subject (sub)
Audience (aud)
Expiration Time (exp)
Not Before (nbf)
Issued At (iat)
JWT ID (jtd)
R e g i s t e r e d C l a i m N a m e s
PAY L O A D
P u b l i c C l a i m N a m e sP r i v a t e C l a i m N a m e s
S I G N AT U R E
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
S I G N AT U R E
RSASHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
-----BEGIN PUBLIC KEY-----
...
,
-----BEGIN RSA PRIVATE KEY-----
...
)
A U T H O R I Z AT I O N
Authorization: Bearer eyJhbGci...lxZpRXHOOw
O A u t h
O p e n A u t h o r i z a t i o n
OAuth (Open Authorization) is an open standard for token-based
authentication and authorization on the Internet.
R E M E B E R
A u t h o r i z a t i o nA u t h e n t i c a t i o n
R E M E B E R
A u t h o r i z a t i o nA u t h e n t i c a t i o n
W h o a r e y o u ?
R E M E B E R
A u t h o r i z a t i o nA u t h e n t i c a t i o n
A r e y o u a l l o w e d t o d o t h a t ?W h o a r e y o u ?
Resource Server
Client App Resource Server
Get user’s data
Client App Resource Server
Get user’s data
Return user’s data
Client App Resource Server
Get user’s data
Return user’s data
Client App Resource Server
Get user’s data
Return user’s data
Client App Resource Server
Client App Resource Server
Client App Resource Server
Access Token
Client App Resource Server
Access Token
Get user’s data
Client App Resource Server
Access Token
Access Token
Get user’s data
Client App Resource Server
Access Token
Access Token
Get user’s data
Access Token
Client App Resource Server
Access Token
Access Token
Get user’s data
Access Token
Verify
Return user’s data
Client App Resource Server
Access Token
Access Token
Get user’s data
Access Token
Verify
Return user’s data
Client App Resource Server
Access Token
Access Token
Get user’s data
Access Token
Verify
Client App Authorization Server
Client App Authorization Server
Access Token
G
enerate
Issue Access Token
Client App Authorization Server
Access Token
G
enerate
Issue Access Token
Client App Authorization Server
Access Token Access Token
G
enerate
Client App
Resource Server
Authorization Server
Client App
Resource Server
Authorization Server
Access Token
G
enerate
Client App
Resource Server
Issue Access Token
Authorization Server
Access Token
G
enerate
Client App
Resource Server
Access Token
Issue Access Token
Authorization Server
Access Token
G
enerate
Client App
Resource Server
Access Token
Get user’s data
Issue Access Token
Authorization Server
Access Token
G
enerate
Client App
Resource Server
Access Token
Access Token
Get user’s data
Issue Access Token
Authorization Server
Access Token
G
enerate
Client App
Resource Server
Access Token
Access Token
Get user’s data Access Token
Issue Access Token
Authorization Server
Access Token
G
enerate
Client App
Resource Server
Access Token
Access Token
Get user’s data Access Token
Verify
Issue Access Token
Authorization Server
Access Token
G
enerate
Return user’s data
Client App
Resource Server
Access Token
Access Token
Get user’s data Access Token
Verify
Issue Access Token
Authorization Server
Access Token
G
enerate
Return user’s data
Client App
Resource Server
Access Token
Access Token
Get user’s data Access Token
Verify
Issue Access Token
Authorization Server
Access Token
G
enerate
S S O
S i n g l e S i g n - O n
G o o g l e S i g n I n F l o w
G o o g l e S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Google
G o o g l e S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Google
2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby
dostać ID Token
G o o g l e S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Google
2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby
dostać ID Token
3. Mobile: User poprawnie loguje się profilem Google
G o o g l e S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Google
2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby
dostać ID Token
3. Mobile: User poprawnie loguje się profilem Google
4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy ID Token, który wysyłamy do API
G o o g l e S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Google
2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby
dostać ID Token
3. Mobile: User poprawnie loguje się profilem Google
4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy ID Token, który wysyłamy do API
5. Backend: Odbiera ID Token i sprawdza jego poprawność
G o o g l e S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Google
2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby
dostać ID Token
3. Mobile: User poprawnie loguje się profilem Google
4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy ID Token, który wysyłamy do API
5. Backend: Odbiera ID Token i sprawdza jego poprawność
6. Backend: Jeśli token jest poprawny to można z niego wyciągnąć dane o użytkowniku i na tej podstawie
stworzyć konto/albo nową sesję
G o o g l e S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Google
2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby
dostać ID Token
3. Mobile: User poprawnie loguje się profilem Google
4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy ID Token, który wysyłamy do API
5. Backend: Odbiera ID Token i sprawdza jego poprawność
6. Backend: Jeśli token jest poprawny to można z niego wyciągnąć dane o użytkowniku i na tej podstawie
stworzyć konto/albo nową sesję
7. Mobile: API zwraca odpowiedź, że logowanie jest poprawne lub niepoprawne (+ tokeny refresh/access)
F a c e b o o k S i g n I n F l o w
F a c e b o o k S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook
F a c e b o o k S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook
2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest
zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView)
F a c e b o o k S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook
2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest
zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView)
3. Mobile: User poprawnie loguje się profilem Facebook
F a c e b o o k S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook
2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest
zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView)
3. Mobile: User poprawnie loguje się profilem Facebook
4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy AccessToken, który wysyłamy do API
F a c e b o o k S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook
2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest
zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView)
3. Mobile: User poprawnie loguje się profilem Facebook
4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy AccessToken, który wysyłamy do API
5. Backend: Odbiera AccessToken, sprawdza jego poprawność z wykorzystaniem endpointu /user z
parametrem me jako user-id (czyli /v3.2/me) oraz dla bezpieczeństwa parametrem appsecret_proof
F a c e b o o k S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook
2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest
zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView)
3. Mobile: User poprawnie loguje się profilem Facebook
4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy AccessToken, który wysyłamy do API
5. Backend: Odbiera AccessToken, sprawdza jego poprawność z wykorzystaniem endpointu /user z
parametrem me jako user-id (czyli /v3.2/me) oraz dla bezpieczeństwa parametrem appsecret_proof
6. Backend: Jeśli token jest poprawny to można z niego wyciągnąć dane o użytkowniku i na tej podstawie
stworzyć konto/albo nową sesję.
F a c e b o o k S i g n I n F l o w
1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook
2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest
zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView)
3. Mobile: User poprawnie loguje się profilem Facebook
4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy AccessToken, który wysyłamy do API
5. Backend: Odbiera AccessToken, sprawdza jego poprawność z wykorzystaniem endpointu /user z
parametrem me jako user-id (czyli /v3.2/me) oraz dla bezpieczeństwa parametrem appsecret_proof
6. Backend: Jeśli token jest poprawny to można z niego wyciągnąć dane o użytkowniku i na tej podstawie
stworzyć konto/albo nową sesję.
7. Mobile: Otrzymujemy odpowiedź, że logowanie jest poprawne lub niepoprawne (+ tokeny refresh/access)
U s e r S e r v i c e
$ composer require lexik/jwt-authentication-bundle
lexik_jwt_authentication:
secret_key: 'secret'
token_ttl: 3600
encoder:
signature_algorithm: 'HS512'
api_login_check:
path: /api/login_check
security:
providers:
in_memory:
memory:
users:
admin: # Test dummy user
password: password
roles: 'ROLE_ADMIN'
encoders:
SymfonyComponentSecurityCoreUserUser: plaintext
firewalls:
login:
pattern: ^/api/login
stateless: true
anonymous: true
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
provider: in_memory
api:
pattern: ^/api
stateless: true
guard:
authenticators: [lexik_jwt_authentication.jwt_token_authenticator]
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
curl -X POST 
https://example.com/api/login_check 
-H 'Content-Type: application/json' 
-d '{"username":"admin","password":"password"}'
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1NjY0NjgzODQsImV4cCI6MTU2N
jQ3MTk4NCwicm9sZXMiOlsiUk9MRV9BRE1JTiJdLCJ1c2VybmFtZSI6ImFkbWluIn0.TJST6ZifM4jIZiuejvMkd0PZ
vwZWlgS6MKsloNBEUHmYTTGyZlcsJx-ol04U-cn2uAzisfv-oHLw7I7k1sqVY5V28RjUg-OBN-CtEzEAh_OL-a-
kweuO0q4KCsv5Pm1R77rahfZ2rZ1Z0j3A6SmOTqEjpVBIOBHO76Gy6hGY7uHiyVgi4hfxhBUV-
Pd1zBxule77upXX9AgWwFnvltbSD3GioUTIlu8k5kizX7_IteZAhXRs7-o0jE3oMPQi0TCQbp7wf_-bSfGmtV-
XoPnxT-
jmvWPGGjAI50_BEgwif8vwXPEn7gHN4nzwrOJd9YjVfn_9l8bsmx_ruqXX0C_FMUlDkcABDsApNJzo3dpeAnEdMYPKo
_jnVMfaV0QcBPrcfBTvldCDW67WaMDC7T9kNUAj4weB48rnjDzveyg6ymzoLanMTMq567pFBWfiVRrQluQ0QKnTtXQD
-qbg4k8wuTlNxZvd1zJ2HPa7U3gH9ZVrwK27P3_7hZzZghPFlhNh-
J_vm7nVd0H4EVIlFj6mtPjnCiXyRugM4g8HYEc_Kx_UnbL4EBkWPpzrT2X9tYQvXnWtyxeWNubHGoizPlxYOAoIZeGT
Lp0HKKSecvvrZLNjea_GP_Fo6KOCC6N4o4cy2FsFdM06Zk6pC_0R-xzOUtqc3-dBkdBrhTyVFc3gbgU"
}
{
"iat":1566468384,
"exp":1566471984,
"roles":["ROLE_ADMIN"],
"username":"admin"
}
S y m f o n y G u a r d
$ composer require symfony/security-guard
interface AuthenticatorInterface
{
public function supports(Request $request): bool;
public function getCredentials(Request $request);
public function getUser($credentials, UserProviderInterface $userProvider): ?UserInterface;
public function checkCredentials($credentials, UserInterface $user): bool;
public function createAuthenticatedToken(UserInterface $user, $providerKey): GuardTokenInterface;
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response;
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey): ?Response;
public function supportsRememberMe(): bool;
}
$ composer require league/oauth2-google
class GoogleAuthenticator implements AuthenticatorInterface
{
…
}
public function supportsRememberMe(): bool
{
return true;
}
public function checkCredentials($credentials, UserInterface $user): bool
{
return true;
}
public function supports(Request $request): bool
{
return $request->attributes->get('_route') === 'api_login_check';
}
public function getUser($credentials, UserProviderInterface $userProvider): UserInterface
{
$googleUser = $this->getClient()->fetchUserFromCredentials($credentials);
$existingUser = $this->repository->findOneBy(['googleId' => $googleUser->getId()]);
if ($existingUser) {
return $existingUser;
}
$user = $this->createUser($googleUser);
$this->em->persist($user);
$this->em->flush();
return $user;
}
protected function createUser(GoogleUser $googleUser): User
{
$user = new User();
$user->setEmail($googleUser->getEmail());
$user->setGoogleEmail($googleUser->getEmail());
$user->setGoogleId($googleUser->getId());
$user->setFirstName($googleUser->getFirstName());
$user->setLastName($googleUser->getLastName());
return $user;
}
protected function getClient(): GoogleClient
{
return $this->clients['google'];
}
public function getCredentials(Request $request): array
{
return $this->getClient()->getCredentialsFromIdToken($request->query->get('id_token', ''));
}
protected function fetchUserFromCredentials(array $credentials): GoogleUser
{
return $this->getClient()->fetchUserFromCredentials($credentials);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey): ?Response
{
// LexikBundleJWTAuthenticationBundleSecurityHttpAuthenticationAuthenticationSuccessHandler
return $this->authenticationSuccessHandler->onAuthenticationSuccess($request, $token);
}
public function onAuthenticationFailure(Request $request, AuthenticationException $authException): ?Response
{
// LexikBundleJWTAuthenticationBundleSecurityHttpAuthenticationAuthenticationFailureHandler
return $this->authenticationFailureHandler->onAuthenticationFailure($request, $authException);
}
public function start(Request $request, AuthenticationException $authException = null): Response
{
$ex = $authException ?? new AuthenticationException('Unknown error');
return $this->authenticationFailureHandler->onAuthenticationFailure($request, $ex);
}
use LeagueOAuth2ClientProviderExceptionIdentityProviderException;
use LeagueOAuth2ClientProviderGoogle;
use LeagueOAuth2ClientProviderGoogleUser;
class GoogleClient
{
public function __construct(string $clientId, string $clientSecret)
{
$this->provider = new Google([
'clientId' => $clientId,
'clientSecret' => $clientSecret,
]);
$this->clientId = $clientId;
}
public function getCredentialsFromIdToken(string $idToken): ?array
{
$request = $this->provider->getRequest('GET', 'https://oauth2.googleapis.com/tokeninfo?id_token=' . $idToken);
$response = $this->provider->getParsedResponse($request);
return $this->validateIdTokenResponse($response) ? $response : null;
}
private function validateIdTokenResponse(array $response): bool
{
return
preg_match('/^(?:https://)?accounts.google.com$/', $response['iss'] ?? '') === 1
&& ($response['aud'] ?? '') === $this->clientId
&& ($response['exp'] ?? 0) > time();
}
public function fetchUserFromCredentials($credentials): GoogleUser
{
return new GoogleUser($credentials);
}
}
AppSecurityAuthenticatorGoogleAuthenticator:
arguments:
- { google: '@AppClientGoogleClient' }
AppClientGoogleClient:
arguments:
- '%env(OAUTH_GOOGLE_ID)%'
- '%env(OAUTH_GOOGLE_SECRET)%'
$ composer require league/oauth2-facebook
class FacebookAuthenticator extends AbstractSocialAuthenticator
{
public function getCredentials(Request $request): FacebookUser {…}
public function getUser($credentials, UserProviderInterface $userProvider): UserInterface {…}
protected function getClient(): FacebookClient {…}
protected function createUser(FacebookUser $facebookUser): User {…}
protected function getService(): string {…}
}
curl -X POST 
https://example.com/api/login_check?service=google&id_token=token
curl -X POST 
https://example.com/api/login_check?service=facebook&id_token=token
E m a i l / P a s s w o r d L o g I n
security:
firewalls:
base_login:
pattern: ^/api/base_login
stateless: true
anonymous: true
provider: in_memory
form_login:
check_path: /api/base_login/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
access_control:
- { path: ^/api/base_login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
api_base_login_check:
path: /api/base_login/login_check
curl -X POST 
https://example.com/api/base_login/login_check 
-H 'Content-Type: application/x-www-form-urlencoded' 
-d '_username=admin&_password=password'
R e f r e s h T o k e n s
$ composer require gesdinet/jwt-refresh-token-bundle
gesdinet_jwt_refresh_token:
ttl: 2592000 #30 days
ttl_update: true
user_identity_field: username
gesdinet_jwt_refresh_token:
path: /api/token/refresh
defaults: { _controller: gesdinet.jwtrefreshtoken:refresh }
security:
firewalls:
refresh:
pattern: ^/api/token/refresh
stateless: true
anonymous: true
access_control:
- { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }
G d z i e t e m i k r o s e r w i s y ?
P Y TA N I A ?
GRZEGORZ STAWARCZYK
grzegorz.stawarczyk@qpony.pl
@gstawarczyk
D Z I Ę K U J Ę !

More Related Content

Featured

Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
Skeleton Technologies
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
Kurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
SpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Lily Ray
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
Rajiv Jayarajah, MAppComm, ACC
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
Christy Abraham Joy
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
Vit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
MindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
GetSmarter
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
Alireza Esmikhani
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
Project for Public Spaces & National Center for Biking and Walking
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
DevGAMM Conference
 

Featured (20)

Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
 

Logowanie użytkowników w REST API na mikroserwisach PHPers Summit 2019

  • 1. L o g o w a n i e u ż y t k o w n i k ó w w R E S T A P I n a m i k r o s e r w i s a c h
  • 2. G R U PA Q P O N Y B L I X P O N A D 3 0 0 0 0 0 0 U Ż Y T K O W N I K Ó W M I E S I Ę C Z N I E
  • 4. J S O N W e b T o k e n
  • 5. J s o n W e b T o k e n JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.
  • 6. J s o n W e b T o k e n eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3O DkwIiwibmFtZSI6IkdyemVnb3J6IiwicGhwZXJzIjoyMDE5LCJpYXQiO jE1MTYyMzkwMjJ9.fDuS4X19nQ9B3c9QWVsbYJqI4ckBXetARlxZp RXHOOw
  • 7. J s o n W e b T o k e n eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3O DkwIiwibmFtZSI6IkdyemVnb3J6IiwicGhwZXJzIjoyMDE5LCJpYXQiO jE1MTYyMzkwMjJ9.fDuS4X19nQ9B3c9QWVsbYJqI4ckBXetARlxZp RXHOOw
  • 8. J s o n W e b T o k e n
  • 9. J s o n W e b T o k e n eyJhbGciOiJIUzI1NiIsInR5cCI6 IkpXVCJ9
  • 10. J s o n W e b T o k e n eyJhbGciOiJIUzI1NiIsInR5cCI6 IkpXVCJ9 { "alg": "HS256", "typ": "JWT" }
  • 11. J s o n W e b T o k e n eyJhbGciOiJIUzI1NiIsInR5cCI6 IkpXVCJ9 eyJzdWIiOiIxMjM0NTY3ODkwI iwibmFtZSI6IkdyemVnb3J6Iiwi cGhwZXJzIjoyMDE5LCJpYXQi OjE1MTYyMzkwMjJ9 { "alg": "HS256", "typ": "JWT" }
  • 12. J s o n W e b T o k e n eyJhbGciOiJIUzI1NiIsInR5cCI6 IkpXVCJ9 eyJzdWIiOiIxMjM0NTY3ODkwI iwibmFtZSI6IkdyemVnb3J6Iiwi cGhwZXJzIjoyMDE5LCJpYXQi OjE1MTYyMzkwMjJ9 { "alg": "HS256", "typ": "JWT" } { "sub": "1234567890", "name": "Grzegorz", "phpers": 2019, "iat": 1516239022 }
  • 13. J s o n W e b T o k e n eyJhbGciOiJIUzI1NiIsInR5cCI6 IkpXVCJ9 eyJzdWIiOiIxMjM0NTY3ODkwI iwibmFtZSI6IkdyemVnb3J6Iiwi cGhwZXJzIjoyMDE5LCJpYXQi OjE1MTYyMzkwMjJ9 fDuS4X19nQ9B3c9QWVsbYJq I4ckBXetARlxZpRXHOOw { "alg": "HS256", "typ": "JWT" } { "sub": "1234567890", "name": "Grzegorz", "phpers": 2019, "iat": 1516239022 }
  • 14. J s o n W e b T o k e n eyJhbGciOiJIUzI1NiIsInR5cCI6 IkpXVCJ9 eyJzdWIiOiIxMjM0NTY3ODkwI iwibmFtZSI6IkdyemVnb3J6Iiwi cGhwZXJzIjoyMDE5LCJpYXQi OjE1MTYyMzkwMjJ9 fDuS4X19nQ9B3c9QWVsbYJq I4ckBXetARlxZpRXHOOw { "alg": "HS256", "typ": "JWT" } { "sub": "1234567890", "name": "Grzegorz", "phpers": 2019, "iat": 1516239022 } HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), PHPers2019 )
  • 15. H E A D E R T y p e A l g o r i t h m HS256 HS384 HS512 RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512 J W T
  • 16. PAY L O A D R e g i s t e r e d C l a i m N a m e s
  • 17. PAY L O A D Issuer (iss) Subject (sub) Audience (aud) Expiration Time (exp) Not Before (nbf) Issued At (iat) JWT ID (jtd) R e g i s t e r e d C l a i m N a m e s
  • 18. PAY L O A D P u b l i c C l a i m N a m e sP r i v a t e C l a i m N a m e s
  • 19. S I G N AT U R E HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
  • 20. S I G N AT U R E RSASHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), -----BEGIN PUBLIC KEY----- ... , -----BEGIN RSA PRIVATE KEY----- ... )
  • 21. A U T H O R I Z AT I O N Authorization: Bearer eyJhbGci...lxZpRXHOOw
  • 22. O A u t h
  • 23. O p e n A u t h o r i z a t i o n
  • 24. OAuth (Open Authorization) is an open standard for token-based authentication and authorization on the Internet.
  • 25. R E M E B E R A u t h o r i z a t i o nA u t h e n t i c a t i o n
  • 26. R E M E B E R A u t h o r i z a t i o nA u t h e n t i c a t i o n W h o a r e y o u ?
  • 27. R E M E B E R A u t h o r i z a t i o nA u t h e n t i c a t i o n A r e y o u a l l o w e d t o d o t h a t ?W h o a r e y o u ?
  • 28.
  • 29.
  • 32. Get user’s data Client App Resource Server
  • 33. Get user’s data Return user’s data Client App Resource Server
  • 34. Get user’s data Return user’s data Client App Resource Server
  • 35. Get user’s data Return user’s data Client App Resource Server
  • 36.
  • 38. Client App Resource Server Access Token
  • 39. Client App Resource Server Access Token Get user’s data
  • 40. Client App Resource Server Access Token Access Token Get user’s data
  • 41. Client App Resource Server Access Token Access Token Get user’s data Access Token
  • 42. Client App Resource Server Access Token Access Token Get user’s data Access Token Verify
  • 43. Return user’s data Client App Resource Server Access Token Access Token Get user’s data Access Token Verify
  • 44. Return user’s data Client App Resource Server Access Token Access Token Get user’s data Access Token Verify
  • 45.
  • 47. Client App Authorization Server Access Token G enerate
  • 48. Issue Access Token Client App Authorization Server Access Token G enerate
  • 49. Issue Access Token Client App Authorization Server Access Token Access Token G enerate
  • 50.
  • 52. Client App Resource Server Authorization Server Access Token G enerate
  • 53. Client App Resource Server Issue Access Token Authorization Server Access Token G enerate
  • 54. Client App Resource Server Access Token Issue Access Token Authorization Server Access Token G enerate
  • 55. Client App Resource Server Access Token Get user’s data Issue Access Token Authorization Server Access Token G enerate
  • 56. Client App Resource Server Access Token Access Token Get user’s data Issue Access Token Authorization Server Access Token G enerate
  • 57. Client App Resource Server Access Token Access Token Get user’s data Access Token Issue Access Token Authorization Server Access Token G enerate
  • 58. Client App Resource Server Access Token Access Token Get user’s data Access Token Verify Issue Access Token Authorization Server Access Token G enerate
  • 59. Return user’s data Client App Resource Server Access Token Access Token Get user’s data Access Token Verify Issue Access Token Authorization Server Access Token G enerate
  • 60. Return user’s data Client App Resource Server Access Token Access Token Get user’s data Access Token Verify Issue Access Token Authorization Server Access Token G enerate
  • 61. S S O
  • 62. S i n g l e S i g n - O n
  • 63. G o o g l e S i g n I n F l o w
  • 64. G o o g l e S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Google
  • 65. G o o g l e S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Google 2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby dostać ID Token
  • 66. G o o g l e S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Google 2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby dostać ID Token 3. Mobile: User poprawnie loguje się profilem Google
  • 67. G o o g l e S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Google 2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby dostać ID Token 3. Mobile: User poprawnie loguje się profilem Google 4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy ID Token, który wysyłamy do API
  • 68. G o o g l e S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Google 2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby dostać ID Token 3. Mobile: User poprawnie loguje się profilem Google 4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy ID Token, który wysyłamy do API 5. Backend: Odbiera ID Token i sprawdza jego poprawność
  • 69. G o o g l e S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Google 2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby dostać ID Token 3. Mobile: User poprawnie loguje się profilem Google 4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy ID Token, który wysyłamy do API 5. Backend: Odbiera ID Token i sprawdza jego poprawność 6. Backend: Jeśli token jest poprawny to można z niego wyciągnąć dane o użytkowniku i na tej podstawie stworzyć konto/albo nową sesję
  • 70. G o o g l e S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Google 2. Mobile: Otwieramy formularz logowania Google z parametrem requestIdToken(serverClientId) żeby dostać ID Token 3. Mobile: User poprawnie loguje się profilem Google 4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy ID Token, który wysyłamy do API 5. Backend: Odbiera ID Token i sprawdza jego poprawność 6. Backend: Jeśli token jest poprawny to można z niego wyciągnąć dane o użytkowniku i na tej podstawie stworzyć konto/albo nową sesję 7. Mobile: API zwraca odpowiedź, że logowanie jest poprawne lub niepoprawne (+ tokeny refresh/access)
  • 71. F a c e b o o k S i g n I n F l o w
  • 72. F a c e b o o k S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook
  • 73. F a c e b o o k S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook 2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView)
  • 74. F a c e b o o k S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook 2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView) 3. Mobile: User poprawnie loguje się profilem Facebook
  • 75. F a c e b o o k S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook 2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView) 3. Mobile: User poprawnie loguje się profilem Facebook 4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy AccessToken, który wysyłamy do API
  • 76. F a c e b o o k S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook 2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView) 3. Mobile: User poprawnie loguje się profilem Facebook 4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy AccessToken, który wysyłamy do API 5. Backend: Odbiera AccessToken, sprawdza jego poprawność z wykorzystaniem endpointu /user z parametrem me jako user-id (czyli /v3.2/me) oraz dla bezpieczeństwa parametrem appsecret_proof
  • 77. F a c e b o o k S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook 2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView) 3. Mobile: User poprawnie loguje się profilem Facebook 4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy AccessToken, który wysyłamy do API 5. Backend: Odbiera AccessToken, sprawdza jego poprawność z wykorzystaniem endpointu /user z parametrem me jako user-id (czyli /v3.2/me) oraz dla bezpieczeństwa parametrem appsecret_proof 6. Backend: Jeśli token jest poprawny to można z niego wyciągnąć dane o użytkowniku i na tej podstawie stworzyć konto/albo nową sesję.
  • 78. F a c e b o o k S i g n I n F l o w 1. Mobile: Użytkownik klika przycisk Zaloguj z Facebook 2. Mobile: Otwieramy formularz logowania Facebook z Facebook SDK (w zależności od tego czy jest zainstalowana aplikacja FB to będzie formularz natywny, jeśli nie jest zainstalowana to PopUp z WebView) 3. Mobile: User poprawnie loguje się profilem Facebook 4. Mobile: W odpowiedzi na poprawne zalogowanie otrzymujemy AccessToken, który wysyłamy do API 5. Backend: Odbiera AccessToken, sprawdza jego poprawność z wykorzystaniem endpointu /user z parametrem me jako user-id (czyli /v3.2/me) oraz dla bezpieczeństwa parametrem appsecret_proof 6. Backend: Jeśli token jest poprawny to można z niego wyciągnąć dane o użytkowniku i na tej podstawie stworzyć konto/albo nową sesję. 7. Mobile: Otrzymujemy odpowiedź, że logowanie jest poprawne lub niepoprawne (+ tokeny refresh/access)
  • 79. U s e r S e r v i c e
  • 80. $ composer require lexik/jwt-authentication-bundle
  • 83. security: providers: in_memory: memory: users: admin: # Test dummy user password: password roles: 'ROLE_ADMIN' encoders: SymfonyComponentSecurityCoreUserUser: plaintext firewalls: login: pattern: ^/api/login stateless: true anonymous: true json_login: check_path: /api/login_check success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure provider: in_memory api: pattern: ^/api stateless: true guard: authenticators: [lexik_jwt_authentication.jwt_token_authenticator] access_control: - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
  • 84. curl -X POST https://example.com/api/login_check -H 'Content-Type: application/json' -d '{"username":"admin","password":"password"}'
  • 85. { "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1NjY0NjgzODQsImV4cCI6MTU2N jQ3MTk4NCwicm9sZXMiOlsiUk9MRV9BRE1JTiJdLCJ1c2VybmFtZSI6ImFkbWluIn0.TJST6ZifM4jIZiuejvMkd0PZ vwZWlgS6MKsloNBEUHmYTTGyZlcsJx-ol04U-cn2uAzisfv-oHLw7I7k1sqVY5V28RjUg-OBN-CtEzEAh_OL-a- kweuO0q4KCsv5Pm1R77rahfZ2rZ1Z0j3A6SmOTqEjpVBIOBHO76Gy6hGY7uHiyVgi4hfxhBUV- Pd1zBxule77upXX9AgWwFnvltbSD3GioUTIlu8k5kizX7_IteZAhXRs7-o0jE3oMPQi0TCQbp7wf_-bSfGmtV- XoPnxT- jmvWPGGjAI50_BEgwif8vwXPEn7gHN4nzwrOJd9YjVfn_9l8bsmx_ruqXX0C_FMUlDkcABDsApNJzo3dpeAnEdMYPKo _jnVMfaV0QcBPrcfBTvldCDW67WaMDC7T9kNUAj4weB48rnjDzveyg6ymzoLanMTMq567pFBWfiVRrQluQ0QKnTtXQD -qbg4k8wuTlNxZvd1zJ2HPa7U3gH9ZVrwK27P3_7hZzZghPFlhNh- J_vm7nVd0H4EVIlFj6mtPjnCiXyRugM4g8HYEc_Kx_UnbL4EBkWPpzrT2X9tYQvXnWtyxeWNubHGoizPlxYOAoIZeGT Lp0HKKSecvvrZLNjea_GP_Fo6KOCC6N4o4cy2FsFdM06Zk6pC_0R-xzOUtqc3-dBkdBrhTyVFc3gbgU" }
  • 87. S y m f o n y G u a r d
  • 88. $ composer require symfony/security-guard
  • 89. interface AuthenticatorInterface { public function supports(Request $request): bool; public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider): ?UserInterface; public function checkCredentials($credentials, UserInterface $user): bool; public function createAuthenticatedToken(UserInterface $user, $providerKey): GuardTokenInterface; public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response; public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey): ?Response; public function supportsRememberMe(): bool; }
  • 90. $ composer require league/oauth2-google
  • 91. class GoogleAuthenticator implements AuthenticatorInterface { … }
  • 92. public function supportsRememberMe(): bool { return true; } public function checkCredentials($credentials, UserInterface $user): bool { return true; } public function supports(Request $request): bool { return $request->attributes->get('_route') === 'api_login_check'; }
  • 93. public function getUser($credentials, UserProviderInterface $userProvider): UserInterface { $googleUser = $this->getClient()->fetchUserFromCredentials($credentials); $existingUser = $this->repository->findOneBy(['googleId' => $googleUser->getId()]); if ($existingUser) { return $existingUser; } $user = $this->createUser($googleUser); $this->em->persist($user); $this->em->flush(); return $user; }
  • 94. protected function createUser(GoogleUser $googleUser): User { $user = new User(); $user->setEmail($googleUser->getEmail()); $user->setGoogleEmail($googleUser->getEmail()); $user->setGoogleId($googleUser->getId()); $user->setFirstName($googleUser->getFirstName()); $user->setLastName($googleUser->getLastName()); return $user; }
  • 95. protected function getClient(): GoogleClient { return $this->clients['google']; } public function getCredentials(Request $request): array { return $this->getClient()->getCredentialsFromIdToken($request->query->get('id_token', '')); } protected function fetchUserFromCredentials(array $credentials): GoogleUser { return $this->getClient()->fetchUserFromCredentials($credentials); }
  • 96. public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey): ?Response { // LexikBundleJWTAuthenticationBundleSecurityHttpAuthenticationAuthenticationSuccessHandler return $this->authenticationSuccessHandler->onAuthenticationSuccess($request, $token); } public function onAuthenticationFailure(Request $request, AuthenticationException $authException): ?Response { // LexikBundleJWTAuthenticationBundleSecurityHttpAuthenticationAuthenticationFailureHandler return $this->authenticationFailureHandler->onAuthenticationFailure($request, $authException); }
  • 97. public function start(Request $request, AuthenticationException $authException = null): Response { $ex = $authException ?? new AuthenticationException('Unknown error'); return $this->authenticationFailureHandler->onAuthenticationFailure($request, $ex); }
  • 98. use LeagueOAuth2ClientProviderExceptionIdentityProviderException; use LeagueOAuth2ClientProviderGoogle; use LeagueOAuth2ClientProviderGoogleUser; class GoogleClient { public function __construct(string $clientId, string $clientSecret) { $this->provider = new Google([ 'clientId' => $clientId, 'clientSecret' => $clientSecret, ]); $this->clientId = $clientId; } public function getCredentialsFromIdToken(string $idToken): ?array { $request = $this->provider->getRequest('GET', 'https://oauth2.googleapis.com/tokeninfo?id_token=' . $idToken); $response = $this->provider->getParsedResponse($request); return $this->validateIdTokenResponse($response) ? $response : null; } private function validateIdTokenResponse(array $response): bool { return preg_match('/^(?:https://)?accounts.google.com$/', $response['iss'] ?? '') === 1 && ($response['aud'] ?? '') === $this->clientId && ($response['exp'] ?? 0) > time(); } public function fetchUserFromCredentials($credentials): GoogleUser { return new GoogleUser($credentials); } }
  • 99. AppSecurityAuthenticatorGoogleAuthenticator: arguments: - { google: '@AppClientGoogleClient' } AppClientGoogleClient: arguments: - '%env(OAUTH_GOOGLE_ID)%' - '%env(OAUTH_GOOGLE_SECRET)%'
  • 100. $ composer require league/oauth2-facebook
  • 101. class FacebookAuthenticator extends AbstractSocialAuthenticator { public function getCredentials(Request $request): FacebookUser {…} public function getUser($credentials, UserProviderInterface $userProvider): UserInterface {…} protected function getClient(): FacebookClient {…} protected function createUser(FacebookUser $facebookUser): User {…} protected function getService(): string {…} }
  • 102. curl -X POST https://example.com/api/login_check?service=google&id_token=token curl -X POST https://example.com/api/login_check?service=facebook&id_token=token
  • 103. E m a i l / P a s s w o r d L o g I n
  • 104. security: firewalls: base_login: pattern: ^/api/base_login stateless: true anonymous: true provider: in_memory form_login: check_path: /api/base_login/login_check success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure require_previous_session: false access_control: - { path: ^/api/base_login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
  • 106. curl -X POST https://example.com/api/base_login/login_check -H 'Content-Type: application/x-www-form-urlencoded' -d '_username=admin&_password=password'
  • 107. R e f r e s h T o k e n s
  • 108. $ composer require gesdinet/jwt-refresh-token-bundle
  • 109. gesdinet_jwt_refresh_token: ttl: 2592000 #30 days ttl_update: true user_identity_field: username
  • 110. gesdinet_jwt_refresh_token: path: /api/token/refresh defaults: { _controller: gesdinet.jwtrefreshtoken:refresh }
  • 111. security: firewalls: refresh: pattern: ^/api/token/refresh stateless: true anonymous: true access_control: - { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }
  • 112. G d z i e t e m i k r o s e r w i s y ?
  • 113.
  • 114.
  • 115. P Y TA N I A ?