Demystifying JWT

There are many common misconceptions surrounding the JWT. One of them, for example, that the JWT is encrypted (actually only signed and encoded with base64url). In practice, I often come across rather strange solutions when only one session identifier is stored in a JWT (in fact, if you work with a session, then you do not need a JWT). Alternatively, the JWT stores only one user ID, whose profile is requested with each request from the database (in fact, the JWT makes sense if you want to reduce the number of requests to the database). Or, even stranger, the JWTs themselves are stored in the database.







One of the objective reasons for this misunderstanding of the role and place of the JWT is that the JWT specification describes the JWT format, and says nothing about how the JWT should be applied.







The desire to write about this arose for a long time. And after looking at another project with a little strange use of JWT, I still decided.







Let's start with the most important demystification. The JWT might look like this:







eyJhbGciOiJSUzI1NiJ9.eyJpcCI6IjE3Mi4yMS4wLjUiLCJqdGkiOiIwNzlkZDMwMGFiODRlM2MzNGJjNWVkMTlkMjg1ZmRmZWEzNWJjYzExMmYxNDJiNmQ5M2Y3YmIxZWFmZTY4MmY1IiwiZXhwIjoxNjA3NTE0NjgxLCJjb3VudCI6MiwidHRsIjoxMH0.gH7dPMvf2TQaZ5uKVcm7DF4glIQNP01Dys7ADgsd6xcxOjpZ7yGhrgd3rMTHKbFyTOf9_EB5NEtNrtgaIsWTtCd3yWq21JhzbmoVXldJKDxjF841Qm4T6JfSth4vvDF5Ex56p7jgL3rkqk6WQCFigwwO2EJfc2ITWh3zO5CG05LWlCEOIJvJErZMwjt9EhmmGlj9B6hSsEGucCm6EDHVlof6DHsvbN2LM3Z9CyiCLNkGNViqr-jkDKbn8UwIuapJOrAT_dumeCWD1RYDL-WNHObaD3owX4iqwHss2yOFrUfdEynahX3jgzHrC36XSRZeEqmRnHZliczz99KeiuHfc56EF11AoxH-3ytOB1sMivj9LID-JV3ihaUj-cDwbPqiaFv0sL-pFVZ9d9KVUBRrkkrwTLVErFVx9UH9mHmIRiO3wdcimBrKpkMIZDTcU9ukAyaYbBlqYVEoTIGpom29u17-b05wY3y12lCA2n4ZqOceYiw3kyd46IYTGeiNmouG5Rb5ld1HJzyqsNDQJhwdibCImdCGhRuKQCa6aANIqFXM-XSvABpzhr1UmxDijzs30ei3AD8tAzkYe2cVhv3AyG63AcFybjFOU8cvchxZ97jCV32jYy6PFphajjHkq1JuZYjEY6kj7L-tBAFUUtjNiy_e0QSSu5ykJaimBsNzYFQ
      
      





If you decode it with base64url, the "secrecy" myth is immediately destroyed:







{"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)
      
      





The first part in curly braces is called the JOSE Header and is described at https://tools.ietf.org/html/rfc7515 . May contain fields, of which the most important alg. If you set {"alg": "none"} - the token is considered valid without a signature. And thus, your API can be accessed by anyone with a manually generated token without a signature. Most libraries currently reject such tokens by default, but check your APIs just in case.







— . , , , jti — exp — . , JWT — .







, , . . , ( ). , , JWT.







JWT — JSON, .







"" , , JWT. ( - — ).







  1. . ( , "" ) , , .







  2. . , . "" API . JWT , — JWT .









, JWT — , , - , .







, , JWT . ( Redis) . — , .







. JWT , JWT ( )? , "-" . "-" .







"-" . "-" , . , , , - .







There is one rather interesting problem with the cancellation of "conditional" tokens. If they are released indefinitely, then in case of cancellation, they will also have to be stored indefinitely. If you release them for a certain period, then logout will occur from the "eternal" session, if during the validity of the token there is no call to the API.







apapacy@gmail.com

December 9, 2020








All Articles