Is that even a right thing to set the JWT token in the cookie?
If you are using an httponly cookie
then yes. It is safe, a lot safer than using Web Storage
(localStorage
or sessionStorage
). Actually storing your JWT token in localStorage
or sessionStorage
allows an XSS attacker to steal users token and send them to his/her own server, On the other hand since httponly
cookie cannot be accessed from javascript
running on browsers, then in case of an XSS attack, the attacker won't have access to the user's JWT.
If you set JWT in cookie you don't have to set the token in Authorization
header on every request since the browser will automatically send it for you to the server which has set the cookie for you.
Keep in mind that as I mentioned, saving JWT in cookie means that server automatically will send the JWT for you to the server, which means it makes you vulnerable against CSRF attacks(if you put the JWT in localStorage
or sessionStorage
you won't be vulnerable to CSRF attack but as I said you would be vulnerable against XSS attacks). So you should prevent CSRF attacks by using CSRF tokens in your application.
What would be the alternative (and yet secure) approach to handle it in a stateless way and manage the javascript limitation?
As I said, put your JWT in an httponly cookie
and in order to bypass the cookie max size limitation enforced by browsers, You can chunk your cookies once they reach the 4kb limit in size. This is what some popular libraries do e.g. next-auth and dotnet
it works like this:
Once your cookies exceeds the 4kb size. You will chunk them and prefix or postfix them with numbers so you know the order in which they should be merged later. For instance if you are trying to set a JWT whose size is 130kb in a cookie named accessToken
then since 130/40 = 3.25 you at least need 4 cookies named accessToken_1
and accessToken_2
and accessToken_3
and accessToken_4
Note that you should try to avoid large cookies since larger cookie means, more data being sent over the internet which means slower request/response.