I'm trying to implement JWT in my authentication system and I have a few questions. To store the token, I could use cookies but it's also possible to use localStorage
or sessionStorage
.
Which would be the best choice?
I have read that JWT protects the site from CSRF. However, I can't imagine how that would work assuming I save the JWT token in cookie storage.
How would it then protect from CSRF?
Update 1
I saw some usage samples like the following:
curl -v -X POST -H "Authorization: Basic VE01enNFem9FZG9NRERjVEJjbXRBcWJGdTBFYTpYUU9URExINlBBOHJvUHJfSktrTHhUSTNseGNh"
How can I implement that when I make a request to server from the browser? I also saw that some implement the token in the URL:
http://exmple.com?jwt=token
If I would make a request via AJAX then I could set an header like jwt: [token]
and then I could read the token from header.
Update 2
I installed the Advanced REST Client Google Chrome extension and was able to pass the token as a custom header. Is it possible to set this header data via Javascript when making a GET request to the server?
To keep them secure, you should always store JWTs inside an httpOnly cookie. This is a special kind of cookie that's only sent in HTTP requests to the server. It's never accessible (both for reading or writing) from JavaScript running in the browser.
A JWT needs to be stored in a safe place inside the user's browser. Any way,you shouldn't store a JWT in local storage (or session storage). If you store it in a LocalStorage/SessionStorage then it can be easily grabbed by an XSS attack. If the answer is helpful, please click "Accept Answer" and upvote it.
Choosing the storage is more about trade-offs than trying to find a definitive best choice. Let's go through a few options:
localStorage
or sessionStorage
)Authorization
header with a Bearer
scheme)example.com
cannot be read by sub.example.com
)Authorization
header)You leverage the browser localStorage
or sessionStorage
API to store and then retrieve the token when performing requests.
localStorage.setItem('token', 'asY-x34SfYPk'); // write console.log(localStorage.getItem('token')); // read
Authorization
headerYou don't need to do anything client-side as the browser will automatically take care of things for you.
Authorization
header with a Bearer
scheme)Authorization
header)You leverage the browser document.cookie
API to store and then retrieve the token when performing requests. This API is not as fine-grained as the Web storage (you get all the cookies) so you need extra work to parse the information you need.
document.cookie = "token=asY-x34SfYPk"; // write console.log(document.cookie); // read
This may seem a weird option, but it does has the nice benefit that you can have storage available to a top-level domain and all sub-domains which is something Web storage won't give you. However, it's more complex to implement.
My recommendation for most common scenarios would be to go with Option 1, mostly because:
Also note that the cookie based options are also quite different, for Option 3 cookies are used purely as a storage mechanism so it's almost as if it was an implementation detail of the client-side. However, Option 2 means a more traditional way of dealing with authentication; for a further read on this cookies vs token thing you may find this article interesting: Cookies vs Tokens: The Definitive Guide.
Finally, none of the options mention it, but use of HTTPS is mandatory of course, which would mean cookies should be created appropriately to take that in consideration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With