Desmistificando JWT

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. ( - — ).







  1. . ( , "" ) , , .







  2. . , . "" 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








All Articles