Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Asegurando APIs en Symfony con JWT

2,022 views

Published on

Los JSON Web Tokens son una forma muy práctica de asegurar nuestras APIs.

En esta charla veremos cuáles son sus propiedades fundamentales, cómo trabajar con ellos y qué opciones tenemos en Symfony, tanto con librerías, como con LexikJWTAuthenticationBundle y su uso del componente Guard.

Published in: Software
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Asegurando APIs en Symfony con JWT

  1. 1. deSymfony 30 junio - 1 julio 2017 Castellón ASEGURANDO APIS EN SYMFONY CON JWT Nacho Martín
  2. 2. deSymfony ¡Muchas gracias a nuestros patrocinadores!
  3. 3. Programo en Limenius Casi todos los proyectos necesitan una API Hacemos aplicaciones a medida con Symfony y React JWT es una buena herramienta para asegurarlas
  4. 4. Por qué es esto necesario
  5. 5. Por qué es esto necesario ¿Por qué no está todo inventado?
  6. 6. Esta charla va de alivios
  7. 7. Esta charla va de alivios
  8. 8. Autenticación con Cookies Cliente (navegador) Servidor BD POST /login_check username: "nacho", password: "patata"
  9. 9. Autenticación con Cookies Cliente (navegador) Servidor BD Obtiene usuario Verifica credenciales Guarda sesión
  10. 10. Autenticación con Cookies Cliente (navegador) Servidor BD Envía cookie al cliente Set-Cookie: PHPSESSIONID=HOLA…
  11. 11. Autenticación con Cookies Cliente (navegador) Servidor BD Usa cookie para identificarse Cookie: PHPSESSIONID=HOLA
  12. 12. Problemas con Cookies Problemas con CORS Implementación no natural en algunos clientes Hay que protegerse contra CSRF Requiere una gestión de sesión y pensar en cómo escalar Mantienen un estado (sesión)
  13. 13. Estado en REST […] communication must be stateless in nature, […], such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.
  14. 14. Cómo siempre, hay razones Requiere una gestión de sesión, y pensar en cómo escalar ¿Qué hacer con un balanceador de carga? ¿Dónde guardar las sesiones?
  15. 15. Alternativas para APIs
  16. 16. Junio 2012
  17. 17. JSON Web Tokens (JWT)
  18. 18. JOSE JSON Object Signing and Encryption { JWT JWA JWS JWE JWK
  19. 19. JOSE JSON Object Signing and Encryption { JWT JWA JWS JWE JWK
  20. 20. JWT solo es un formato de tokens Pero muchas veces decimos “usar JWT” Para referirnos a una forma de trabajar con ellos https://www.flickr.com/photos/tokencompany/8073379662
  21. 21. Autenticación con JWT Cliente (navegador) Servidor BD POST /login_check username: "nacho", password: "patata"
  22. 22. Autenticación con JWT Cliente (navegador) Servidor BD Obtiene usuario Verifica credenciales Guarda sesión?
  23. 23. Autenticación con JWT Cliente (navegador) Servidor BD Envía token al cliente {“token”:"tomaUnToken"}
  24. 24. Autenticación con JWT Cliente (navegador) Servidor BD Usa token para identificarse Authorization: Bearer tomaUnToken
  25. 25. Uso en JavaScript fetch(baseUrl + '/admin/api/recipes', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer '+token, }, body: JSON.stringify( data ) })
  26. 26. Almacenamiento en JavaScript window.localStorage.setItem('access_token', token) window.localStorage.getItem('access_token')
  27. 27. Almacenamiento en JavaScript window.localStorage.setItem('access_token', token) window.localStorage.getItem('access_token') Ya no tenemos CSRF, ahora ojo con ataques XSS
  28. 28. El famoso token eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwid XNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3Niw iZXhwIjoxNDk4MTQ1Njc2fQ
  29. 29. eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwid XNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3Niw iZXhwIjoxNDk4MTQ1Njc2fQ El famoso token
  30. 30. eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwid XNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3Niw iZXhwIjoxNDk4MTQ1Njc2fQ Hay un punto El famoso token
  31. 31. El famoso token eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwid XNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3Niw iZXhwIjoxNDk4MTQ1Njc2fQ
  32. 32. El famoso token eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwid XNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3Niw iZXhwIjoxNDk4MTQ1Njc2fQ {“alg":"none"} { “username":"nacho", “iat":1498142076, “exp”:1498145676 }
  33. 33. Base64Url eyJhbGciOiJSUzI1NiJ9{“alg":"none"} No está cifrado (todos lo pueden leer) Solo está codificado Esto solo sirve para que pueda viajar en URLs Y en cualquier sitio donde puedan viajar strings
  34. 34. Base64Url { “username":"nacho", “iat":1498142076, “exp”:1498145676 } ¿Me puedo fiar de esto?
  35. 35. Base64Url { “username":"nacho", “iat":1498142076, “exp”:1498145676 } ¿Me puedo fiar de esto?
  36. 36. El token completo eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3NiwiZXh wIjoxNDk4MTQ1Njc2fQ.jomtnO16Tik6jxU_0HmsXFxbUSyBoNTu8RVSbQ9jEKUfYEFTG8QZrsSpNl5uzlXf- hP2zx1YmPTow1jXGyoFjV6Nk1e7pFlw2s8fSrIZpT2ZFBuVPefKhSWXYoSUHGZWtMFMU- yghnWA6tlFD5UcJiDQ3ZlUCbLxOlDdygUoC841aR9R87otefdQUEKY_faGq1Tl- KxJfjndG4HENgC7M52JaX5xFKmOlI1mKXqDvVOrCTil3yOcqxQv94SZjqhG5V7NLaaslMDXVl4fzJC- WWE_Eo0xzfOSxMAZ7NBEvha207pjl8FAszQDZ0uuqxfPLqb4QnpALnFAGip4hlu28wRccAsWJQ6uSYtClrE9Kwt7Vlo4PrPX3zqMb _YaRI1QUco6qjj2AsCf18-0f5XvgqrwSoU_73w4pgsj7rUyft9mwe3tiUYCoUP_dKFJfcz_ofHScpsWfFJ4lD4TIzpKf1LfLFwRUcpQuJdR K8-1C_x5dJILrO2fSKZbxFCq_- zB2UHmbH8eFQQYxIpS4eDjFDZTeFLOzruapM10taDQ8buGOyVUx9vwTJoWq9dFuqVAdhFc9h6iXNy0QzI46uvN- en1n6KVsKTfaLecvCYhIIt32Z5mYD3YgDEeRnLZ5TIgykiVNL9SZCGphzv6h5MEs_xQyDo6XOsu92tPtbqyvI4
  37. 37. El token completo eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJuYWNobyIsImlhdCI6MTQ5ODE0MjA3NiwiZXh wIjoxNDk4MTQ1Njc2fQ.jomtnO16Tik6jxU_0HmsXFxbUSyBoNTu8RVSbQ9jEKUfYEFTG8QZrsSpNl5uzlXf- hP2zx1YmPTow1jXGyoFjV6Nk1e7pFlw2s8fSrIZpT2ZFBuVPefKhSWXYoSUHGZWtMFMU- yghnWA6tlFD5UcJiDQ3ZlUCbLxOlDdygUoC841aR9R87otefdQUEKY_faGq1Tl- KxJfjndG4HENgC7M52JaX5xFKmOlI1mKXqDvVOrCTil3yOcqxQv94SZjqhG5V7NLaaslMDXVl4fzJC- WWE_Eo0xzfOSxMAZ7NBEvha207pjl8FAszQDZ0uuqxfPLqb4QnpALnFAGip4hlu28wRccAsWJQ6uSYtClrE9Kwt7Vlo4PrPX3zqMb _YaRI1QUco6qjj2AsCf18-0f5XvgqrwSoU_73w4pgsj7rUyft9mwe3tiUYCoUP_dKFJfcz_ofHScpsWfFJ4lD4TIzpKf1LfLFwRUcpQuJdR K8-1C_x5dJILrO2fSKZbxFCq_- zB2UHmbH8eFQQYxIpS4eDjFDZTeFLOzruapM10taDQ8buGOyVUx9vwTJoWq9dFuqVAdhFc9h6iXNy0QzI46uvN- en1n6KVsKTfaLecvCYhIIt32Z5mYD3YgDEeRnLZ5TIgykiVNL9SZCGphzv6h5MEs_xQyDo6XOsu92tPtbqyvI4 header.claims.signature
  38. 38. Pero sí está firmado (los intermediarios no lo pueden modificar sin que nos enteremos) No está cifrado
  39. 39. Header { “typ”:”JWT”, “alg”:”RS256” }
  40. 40. Header { “typ”:”JWT”, “alg”:”RS256” } Tipo de token
  41. 41. Header { “typ”:”JWT”, “alg”:”RS256” } Tipo de token Algoritmo de hashing
  42. 42. ¿Qué algoritmo usar? JWA (rfc7518)
  43. 43. Diferencia simétrico/asimétrico Simétrico: usamos la misma clave para firmar y validar. Asimétrico: usamos distintas claves para firmar y validar.
  44. 44. RS256 RS384 RS512 Algoritmos HS256 HS384 HS512 ES256 ES384 ES512 HMAC ECDSA RSA PS256 PS384 PS348 RSASSA-PSS none
  45. 45. RS256 RS384 RS512 Algoritmos HS256 HS384 HS512 ES256 ES384 ES512 HMAC ECDSA RSA PS256 PS384 PS348 RSASSA-PSS none Simétrico
  46. 46. RS256 RS384 RS512 Algoritmos HS256 HS384 HS512 ES256 ES384 ES512 HMAC ECDSA RSA PS256 PS384 PS348 RSASSA-PSS none Simétrico Asimétricos
  47. 47. RS256 RS384 RS512 Algoritmos HS256 HS384 HS512 ES256 ES384 ES512 HMAC ECDSA RS256 RS384 RS512 RSA PS256 PS384 PS348 RSASSA-PSS none Simétrico Asimétricos
  48. 48. Claims { “username":"nacho", “iat":1498142076, “exp”:1498145676 }
  49. 49. Registered claims jti iss aud sub iat exp nbf Id del token: String Issuer (emisor): StringOrUri Audiencia: StringOrUri Subject (tema): StringOrUri Cuándo se creó: NumericDate Cuándo expira: NumericDate Tiempo hasta válidez: NumericDate
  50. 50. Custom claims { “username":"nacho", “iat":1498142076, “exp”:1498145676 } Podemos añadir lo que queramos. Solo hay que tener en cuenta: Ser conciso. Los datos no van cifrados (el cliente los ve).
  51. 51. Firma Signature = algoritmo(payload, key) Payload = Base64URL(headers) + ”.” + Base64URL(claims) JWS (rfc7515)
  52. 52. JWT.IO
  53. 53. Importante: Usar TLS (“SSL”)
  54. 54. Ventajas de JWT
  55. 55. Caso: Mi app en JavaScript se ve distinta dependiendo del rol del usuario
  56. 56. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA
  57. 57. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Tengo una cookie pero no sé qué usuario soy ni qué permisos tengo
  58. 58. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA
  59. 59. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Obtener usuario
  60. 60. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Obtener usuario
  61. 61. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Obtener usuario
  62. 62. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Obtener usuario
  63. 63. Con Cookies Cliente Servidor BD Cookie: PHPSESSIONID=HOLA Obtener usuario Y ahora mostramos
  64. 64. Con JWT Cliente Servidor BD Token: ejh9…
  65. 65. Con JWT Cliente Servidor BD Token: ejh9… { “username":"nacho", “iat":1498142076, “exp”:1498145676 }
  66. 66. Con JWT Cliente Servidor BD Token: ejh9… { “username":"nacho", “iat":1498142076, “exp”:1498145676 } Tenemos todos los datos
  67. 67. Con JWT Cliente Token: ejh9… { “username":"nacho", “iat":1498142076, “exp”:1498145676 } Tenemos todos los datos
  68. 68. Microservicios Auth Clave privada y pública Consulta Clave pública Cliente Clave pública Pedidos Clave pública
  69. 69. Microservicios Auth Clave privada y pública Consulta Clave pública Cliente Clave pública Pedidos Clave pública { “aud”:”consulta", }
  70. 70. Microservicios Auth Clave privada y pública Consulta Clave pública Cliente Clave pública Pedidos Clave pública { “aud”:”consulta", } ✘
  71. 71. Microservicios Auth Clave privada Consulta Cliente Clave pública Clave pública Pedidos Gateway
  72. 72. Soporte en PHP
  73. 73. lcobucci/jwt
  74. 74. Crear tokens use LcobucciJWTBuilder; use LcobucciJWTSignerKeychain; use LcobucciJWTSignerRsaSha256; $signer = new Sha256(); $keychain = new Keychain(); $privateKey = $keychain->getPrivateKey('file://path'); $token = (new Builder())->setIssuer('http://example.com') ->setAudience('http://example.org') ->setId('4f1g23a12aa', true) ->setIssuedAt(time()) ->setNotBefore(time() + 60) ->setExpiration(time() + 3600) ->set('uid', 1) ->sign($signer, $privateKey) ->getToken();
  75. 75. Validar tokens use LcobucciJWTSignerKeychain; use LcobucciJWTSignerRsaSha256; use LcobucciJWTValidationData; $signer = new Sha256(); $keychain = new Keychain(); $publicKey = $keychain->getPublicKey('file://path'); $data = newValidationData(); $data->setIssuer('http://example.com'); $data->setAudience('http://example.org'); $data->setId('4f1g23a12aa'); $token->validate($data); $token->verify($signer, $publicKey);
  76. 76. LexikJWTAuthenticationBundle
  77. 77. Instalación composer require lexik/jwt-authentication-bundle $bundles = array( // ... new LexikBundleJWTAuthenticationBundleLexikJWTAuthenticationBundle(), // ... ); app/config/AppKernel.php
  78. 78. Crear claves $ openssl genrsa -out var/jwt/private.pem -aes256 4096 $ openssl rsa -pubout -in app/jwt/private.pem -out var/jwt/public.pem
  79. 79. Crear claves $ openssl genrsa -out var/jwt/private.pem -aes256 4096 $ openssl rsa -pubout -in app/jwt/private.pem -out var/jwt/public.pem Clave privada
  80. 80. Crear claves $ openssl genrsa -out var/jwt/private.pem -aes256 4096 $ openssl rsa -pubout -in app/jwt/private.pem -out var/jwt/public.pem Clave privada Clave pública
  81. 81. Configuración app/config/parameters.yml app/config/config.yml lexik_jwt_authentication: private_key_path: %jwt_private_key_path% public_key_path: %jwt_public_key_path% pass_phrase: %jwt_key_pass_phrase% token_ttl: %jwt_token_ttl% parameters: jwt_private_key_path: '%kernel.root_dir%/../var/jwt/private.pem' jwt_public_key_path: '%kernel.root_dir%/../var/jwt/public.pem' jwt_key_pass_phrase: patata jwt_token_ttl: 3600
  82. 82. Configuración app/config/parameters.yml app/config/config.yml lexik_jwt_authentication: private_key_path: %jwt_private_key_path% public_key_path: %jwt_public_key_path% pass_phrase: %jwt_key_pass_phrase% token_ttl: %jwt_token_ttl% encoder: service: lexik_jwt_authentication.encoder.lcobucci parameters: jwt_private_key_path: '%kernel.root_dir%/../var/jwt/private.pem' jwt_public_key_path: '%kernel.root_dir%/../var/jwt/public.pem' jwt_key_pass_phrase: patata jwt_token_ttl: 3600
  83. 83. Configuración app/config/parameters.yml app/config/config.yml lexik_jwt_authentication: private_key_path: %jwt_private_key_path% public_key_path: %jwt_public_key_path% pass_phrase: %jwt_key_pass_phrase% token_ttl: %jwt_token_ttl% encoder: service: lexik_jwt_authentication.encoder.lcobucci parameters: jwt_private_key_path: '%kernel.root_dir%/../var/jwt/private.pem' jwt_public_key_path: '%kernel.root_dir%/../var/jwt/public.pem' jwt_key_pass_phrase: patata jwt_token_ttl: 3600 Probablemente será default en algún punto
  84. 84. firewalls: login: pattern: ^/api/login stateless: true anonymous: true form_login: check_path: /api/login_check success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure require_previous_session: false api: pattern: ^/api stateless: true guard: authenticators: - lexik_jwt_authentication.jwt_token_authenticator Security config app/config/security.yml
  85. 85. firewalls: login: pattern: ^/api/login stateless: true anonymous: true form_login: check_path: /api/login_check success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure require_previous_session: false api: pattern: ^/api stateless: true guard: authenticators: - lexik_jwt_authentication.jwt_token_authenticator Security config app/config/security.yml No asigna cookies
  86. 86. Routing config app/config/routing.yml api_login_check: path: /api/login_check
  87. 87. Extender el bundle
  88. 88. Eventos JWT_CREATED: Añadir/quitar datos a claims. JWT_DECODED: Validaciones extra. JWT_AUTHENTICATED: Añadir datos al token de Symfony. AUTHENTICATION_FAILURE JWT_INVALID JWT_NOT_FOUND JWT_EXPIRED }Cambiar respuestas. AUTHENTICATION_SUCCESS
  89. 89. Añadir/quitar datos a payload class JWTCreatedListener { public function onJWTCreated(JWTCreatedEvent $event) { $payload = $event->getData(); $user = $event->getUser(); if ($user->canOrder()) { $payload['aud'] = ‘pedidos'; } $event->setData($payload); } }
  90. 90. Comprobaciones extra class JWTDecodedListener { public function onJWTDecoded(JWTDecodedEvent $event) { $payload = $event->getPayload(); if (!isset($payload['aud']) || $payload['aud'] !== 'pedidos') { $event->markAsInvalid(); } } }
  91. 91. Añadir atributo API a Token Sf class JWTAuthenticatedListener { public function onJWTAuthenticated(JWTAuthenticatedEvent $event) { $token = $event->getToken(); $token->setAttribute('api', true); } } public function pagesAction(Request $request) { if ($this->get(‘security.token_storage') ->getToken() ->getAttribute(‘api')) { return new JsonResponse('hola usuario de api'); } }
  92. 92. ¿Qué pasa si quiero…? Tener diferentes estrategias en distintos firewalls Hacer algo muy particular
  93. 93. Security
  94. 94. AuthenticationProviderInterface Security
  95. 95. AuthenticationProviderInterface UserProvider Security
  96. 96. AuthenticationEntryPointInterface AuthenticationProviderInterface UserProvider Security
  97. 97. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface UserProvider Security
  98. 98. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface UserProvider Security Events
  99. 99. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface UserProvider Security Events UserInterface
  100. 100. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface AbstractToken UserProvider Security Events UserInterface
  101. 101. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface AbstractToken UserProvider Security Voters Events UserInterface
  102. 102. UserProvider
  103. 103. UserProvider
  104. 104. 👌
  105. 105. AuthenticationListener AuthenticationEntryPointInterface AuthenticationProviderInterface AbstractToken UserProvider Security Voters Events UserInterface
  106. 106. Guard 💂
  107. 107. 👌
  108. 108. La interfaz GuardAuthenticator interface GuardAuthenticatorInterface { public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request,AuthenticationException $exception); public function onAuthenticationSuccess(Request $request,TokenInterface $token, $providerKey); public function supportsRememberMe(); }
  109. 109. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe
  110. 110. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe Validar token
  111. 111. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe Validar token Obtener usuario a partir de JWT
  112. 112. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe Validar token Obtener usuario a partir de JWT true
  113. 113. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe Validar token Obtener usuario a partir de JWT true Crear token de Symfony (no JWT)
  114. 114. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe Devolver respuesta adecuada Validar token Obtener usuario a partir de JWT true Crear token de Symfony (no JWT)
  115. 115. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe No hacer nada Devolver respuesta adecuada Validar token Obtener usuario a partir de JWT true Crear token de Symfony (no JWT)
  116. 116. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe false No hacer nada Devolver respuesta adecuada Validar token Obtener usuario a partir de JWT true Crear token de Symfony (no JWT)
  117. 117. La interfaz GuardAuthenticator getCredentials getUser checkCredentials createAuthenticatedToken onAuthenticationFailure onAuthenticationSuccess supportsRememberMe false No hacer nada Devolver respuesta adecuada Validar token Obtener usuario a partir de JWT true Crear token de Symfony (no JWT)
  118. 118. JWTTokenAuthenticator use LexikBundleJWTAuthenticationBundleSecurityGuardJWTTokenAuthenticator as BaseAuthenticator; class MiTokenAuthenticator extends BaseAuthenticator { } security: # ... firewalls: # ... otra_api: pattern: ^/otraapi stateless: true guard: authenticators: - app.mi_token_authenticator
  119. 119. FAQ
  120. 120. Oauth vs JWT? Oauth + JWT?
  121. 121. Usos fuera de headers token_extractors: authorization_header: enabled: true prefix: Bearer name: Authorization cookie: enabled: false name: BEARER query_parameter: enabled: false name: bearer
  122. 122. Cuántos datos caben en un token? https://www.flickr.com/photos/highwaysagency/6008275527
  123. 123. Invalidar tokens
  124. 124. Enlaces con caducidad $user = $this->getUser(); $jwtManager = $this->get('lexik_jwt_authentication.jwt_manager'); $token2 = $jwtManager->create($user); <a href="{{ path('reset_password', {'bearer':authToken.credentials}) }}”> Reset password </a> Controlador Vista
  125. 125. Renovar tokens 👌
  126. 126. Impersonar usuarios en APIs 👌
  127. 127. Impersonar usuarios en APIs HEADER: X-Switch-User: johndoe
  128. 128. Requests a otros dominios 👌
  129. 129. Ejemplo de uso con React
  130. 130. ¡Gracias! @nacmartin nacho@limenius.com http://limenius.com Formación, consultoría y desarrollo de proyectos

×