Existem muitos equívocos comuns em torno do JWT. Uma é, por exemplo, que o JWT é criptografado (na verdade, apenas assinado e codificado em base64url). Na prática, geralmente encontro soluções bastante estranhas quando apenas um identificador de sessão é armazenado em um JWT (na verdade, se você trabalha com uma sessão, não precisa de um JWT). Como alternativa, o JWT armazena apenas um ID de usuário, cujo perfil é solicitado para cada solicitação do banco de dados (na verdade, o JWT faz sentido se você deseja reduzir o número de solicitações ao banco de dados). Ou, ainda mais estranho, os próprios JWTs são armazenados no banco de dados.
Uma das razões objetivas para esse mal-entendido sobre a função e o lugar do JWT é que a especificação do JWT descreve o formato do JWT e não diz nada sobre como o JWT deve ser aplicado.
A vontade de escrever sobre isso já existe há muito tempo. E depois de olhar para outro projeto com um uso um pouco estranho do JWT, eu ainda decidi.
Vamos começar com a desmistificação mais importante. O JWT pode ter a seguinte aparência:
eyJhbGciOiJSUzI1NiJ9.eyJpcCI6IjE3Mi4yMS4wLjUiLCJqdGkiOiIwNzlkZDMwMGFiODRlM2MzNGJjNWVkMTlkMjg1ZmRmZWEzNWJjYzExMmYxNDJiNmQ5M2Y3YmIxZWFmZTY4MmY1IiwiZXhwIjoxNjA3NTE0NjgxLCJjb3VudCI6MiwidHRsIjoxMH0.gH7dPMvf2TQaZ5uKVcm7DF4glIQNP01Dys7ADgsd6xcxOjpZ7yGhrgd3rMTHKbFyTOf9_EB5NEtNrtgaIsWTtCd3yWq21JhzbmoVXldJKDxjF841Qm4T6JfSth4vvDF5Ex56p7jgL3rkqk6WQCFigwwO2EJfc2ITWh3zO5CG05LWlCEOIJvJErZMwjt9EhmmGlj9B6hSsEGucCm6EDHVlof6DHsvbN2LM3Z9CyiCLNkGNViqr-jkDKbn8UwIuapJOrAT_dumeCWD1RYDL-WNHObaD3owX4iqwHss2yOFrUfdEynahX3jgzHrC36XSRZeEqmRnHZliczz99KeiuHfc56EF11AoxH-3ytOB1sMivj9LID-JV3ihaUj-cDwbPqiaFv0sL-pFVZ9d9KVUBRrkkrwTLVErFVx9UH9mHmIRiO3wdcimBrKpkMIZDTcU9ukAyaYbBlqYVEoTIGpom29u17-b05wY3y12lCA2n4ZqOceYiw3kyd46IYTGeiNmouG5Rb5ld1HJzyqsNDQJhwdibCImdCGhRuKQCa6aANIqFXM-XSvABpzhr1UmxDijzs30ei3AD8tAzkYe2cVhv3AyG63AcFybjFOU8cvchxZ97jCV32jYy6PFphajjHkq1JuZYjEY6kj7L-tBAFUUtjNiy_e0QSSu5ykJaimBsNzYFQ
Se você decodificá-lo com base64url, o mito do "sigilo" é imediatamente destruído:
{"alg":"RS256"}{"ip":"172.21.0.5","jti":"079dd300ab84e3c34bc5ed19d285fdfea35bcc112f142b6d93f7bb1eafe682f5","exp":1607514681,"count":2,"ttl":10} O2Mrn%!OPzN{hk11l\9 Mkd Z&ۚWJP%^DǞ8*Xև|!䵥C&D0Di?Ak nue7bݟB 6AV*9)S.jNv `EcG9ތ*6kQDv_xzߥEdgbs<wP( Ӂ"?K ?WxiHp<>,/EU]T䒼-Q+\}P fbuȦ 7 ɦZTJ jhonӜ-v 6j9ǘ :!z#fEewQ*44 bl"&t!F *s>]+U&8z-@Fap2p\S܇}0hˣŦy*ԛb1H/A U3bA$) j)
A primeira parte entre chaves é chamada de Cabeçalho JOSE e é descrita em https://tools.ietf.org/html/rfc7515 . Pode conter campos, dos quais o alg. Se você definir {"alg": "none"} - o token é considerado válido sem uma assinatura. E, assim, sua API pode ser acessada por qualquer pessoa com um token gerado manualmente sem uma assinatura. Atualmente, a maioria das bibliotecas rejeita esses tokens por padrão, mas verifique suas APIs por precaução.
— . , , , jti — exp — . , JWT — .
, , . . , ( ). , , JWT.
JWT — JSON, .
"" , , JWT. ( - — ).
. ( , "" ) , , .
. , . "" API . JWT , — JWT .
, JWT — , , - , .
, , JWT . ( Redis) . — , .
. JWT , JWT ( )? , "-" . "-" .
"-" . "-" , . , , , - .
Há um problema bastante interessante com o cancelamento de tokens "condicionais". Se forem liberados indefinidamente, em caso de cancelamento, também deverão ser armazenados indefinidamente. Se você liberá-los por um determinado período, o logout ocorrerá da sessão "eterna", se durante a validade do token não houver chamada de API.
apapacy@gmail.com
9 de dezembro de 2020