Actualmente estoy aprendiendo la implementación de JWT con PHP y quiero usar tokens JWT en lugar de sesiones para mi aplicación RESTful.
Durante la creación de la firma, estoy haciendo algo como esto
token = base64Header + '.' + base64Payload + '.' + signatureAquí solo estamos usando base64 el Payload. Si pego en sitios como https://jwt.io/#debugger , la carga útil se descifra (incluso si la firma es incorrecta).
Mis preguntas,
A continuación se muestra el código de muestra que escribí
<?php $headers = base64_encode(json_encode([ "typ" => "JWT", "alg" => "HS256" ])); $claims = base64_encode(json_encode([ "sub" => "1234567890", "name" => "John Doe", "admin" => true, "jti" => "870a3de5-ea7b-4062-abef-11180e530f5a", "iat" => 1492603378, "exp" => 1492606978 ])); $payload = $headers.".".$claims; $signature = base64_encode(hash_hmac("sha256", $payload, 'secret', true)); $encodedJWT = $payload.".".$signature; // eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6Ijg3MGEzZGU1LWVhN2ItNDA2Mi1hYmVmLTExMTgwZTUzMGY1YSIsImlhdCI6MTQ5MjYwMzM3OCwiZXhwIjoxNDkyNjA2OTc4fQ.nvw-bAUgr7H_xr3q8_Yz8rCNtMohtn2YlCmcLoLBWlcSi pego en sitios como https://jwt.io/#debugger , la carga útil se descifra (incluso si la firma es incorrecta).
Los terceros no pueden verificar la firma porque no tienen la clave secreta. La carga útil no se descifra, se decodifica.
Idealmente, no debe almacenar datos confidenciales en la carga útil, ya que la carga útil solo está codificada en base64 y no está cifrada. Esto significa que cualquiera que obtenga el token puede ver el contenido de la carga útil simplemente decodificándolo en base64.
Si tiene un token en el almacenamiento local de un navegador web y su sitio tiene una vulnerabilidad XSS, es trivial robar el token. Ya es bastante malo que el atacante tenga un JWT válido (que, con suerte, caducará pronto de todos modos), pero si contiene datos confidenciales, entonces está en un verdadero problema. Imagine tener que notificar a todos los usuarios de su sitio que ahora deben cambiar varios fragmentos de datos confidenciales sobre ellos mismos debido a un posible compromiso masivo.
Mantenga el JWT liviano. Almacene la identificación de los usuarios, sus roles/concesiones dentro del sistema. Si siente que tiene que agregar datos confidenciales a la carga útil, intente reconsiderar su solución.
No, no solo hay JWT firmado (JWS - RFC 7515) , sino también JWT encriptado (JWE - RFC 7516) .
Cuando un JWT está encriptado, puede compartir datos confidenciales de forma segura (a menos que el algoritmo o la clave estén comprometidos).
Pero en su ejemplo, no veo datos confidenciales, por lo que me pregunto si es realmente importante usar JWE en su caso. Le recomiendo que lea esta publicación de blog sobre JWT y las sesiones y por qué no debería usarlos para ese propósito (también eche un vistazo a esa parte 2 ).
Si realmente desea usar JWE, escribí una biblioteca PHP que ya puede cargar y crear cualquier tipo de José (JWS/JWE) y que admite casi todos los algoritmos del RFC 7518 de fábrica. Es posible que existan otras bibliotecas, pero no hay una lista de referencias ( https://jwt.io/ enumera solo las implementaciones de JWS).
Como entendí, está tratando de tener un servidor stateless completo, por lo que desea almacenar incluso datos confidenciales dentro del token.
Pero su servidor no puede ser completamente apátrida. Porque para la funcionalidad de cierre de sesión, debe tener una lista negra o una lista blanca para invalidar el token. Así que en cada solicitud debes tocar la base de datos . Si no tiene una lista negra o una lista blanca , los tokens siguen siendo válidos incluso cuando el usuario cierra la sesión.
Por lo tanto, es mejor obtener los datos confidenciales de la base de datos, ya que debe tocar su base de datos por cada solicitud.