How do I store JWT and send them with every request using react

41,628

Solution 1

Do not store the token in localStorage, the token can be compromised using xss attack. I think the best solution will be to provide both access token and refresh token to the client on login action. save the access token in memory (e.g redux state) and the refresh token should be created on the server with httpOnly flag (and also secure flag if possible). The access token should be set to expire every 2-3 minutes. In order to make sure that the user will not have to enter his credentials every 2-3 minutes I have an interval which calls the /refreshToken endpoint before the current token expires (silent refresh token).

that way, the access token cannot be compromised using xss/csrf. but using an xss attack, the attacker can make a call on your behalf to the /refreshToken endpoint, but this will not be harmful because the returned token cannot be compromised.

Solution 2

1- login component send a login request to the API server endpoint

2- server API endpoint returns a token

3- I save the token in user's localStorage

4- all the API calls from now on will have in the header

Example: https://github.com/joshgeller/react-redux-jwt-auth-example

Security update: As @Dan mentioned in the comment, tokens should not be stored in Localstorage because every javascript script has access to that one, which means third party scripts you don't own could access tokens and do whatevery they want with it.

A better place is to store it as a Cookie with HttpOnly flag.

Solution 3

Since saving the JWT in localStorage is vulnerable to XSS attacks, the other way can be saving it inside a httpOnly cookie but too bad that you cannot do that in frontend, check this post.

The only option you have is to configure your server-side to return you a the JWT in a httpOnly cookie and also accept the token inside httpOnly cookie. You'll also have to think of how you want to deal with token expiry.

NOTE: While modern browsers support and prevent reading/writing via httpOnly cookies, but I am not sure about old browsers.

Share:
41,628
MaieonBrix
Author by

MaieonBrix

Updated on September 26, 2021

Comments

  • MaieonBrix
    MaieonBrix over 2 years

    So happy right know because I got my basic registration/authentication system going on.

    so basically I got this :

    app.post('/login', function(req,res) {
     Users.findOne({
    email: req.body.email
    }, function(err, user) {
    if(err) throw err;
    
    if(!user) {
      res.send({success: false, message: 'Authentication Failed, User not found.'});
    } else {
      //Check passwords
      checkingPassword(req.body.password, user.password, function(err, isMatch) {
        if(isMatch && !err) {
          //Create token
          var token = jwt.sign(user,db.secret, {
            expiresIn: 1008000
          });
          res.json({success: true, jwtToken: "JWT "+token});
        } else {
          res.json({success: false, message: 'Authentication failed, wrong password buddy'});
    
           }
         });
        }
     });
    });
    

    Then I secure my /admin routes and with POSTMAN whenever I send a get request with the jwt in the header everything works perfectly.

    Now here is the tricky part, basically When i'm going to login if this a sucess then redirect me to the admin page, and everytime I try to access admin/* routes I want to send to the server my jwToken but the problem is, how do I achieve that ? I'm not using redux/flux, just using react/react-router.

    I don't know how the mechanic works.

    Thanks guys

  • Dan
    Dan over 5 years
    Putting tokens in LocalStorage is not recommended. See: dev.to/rdegges/please-stop-using-local-storage-1i04
  • 5ervant - techintel.github.io
    5ervant - techintel.github.io about 5 years
    @Dan So what is recommended?
  • Dan
    Dan about 5 years
    Have your server save the JWT token as an HttpOnly cookie. The browser will handle the rest. If you are in a situation where your front end is making CORS requests for the token, you will need to set the withcredentials flag for AJAX requests.
  • itay312
    itay312 about 4 years
    This should not be the selected answer. storing JWT in localStorage will expose the token for xss attacks.
  • RollerCosta
    RollerCosta about 4 years
    first we should not store it in local storage, secondly we can't store it in HttpOnly cookie if we need to read it to send in subsequent http requests.
  • dima
    dima almost 4 years
    Recommending to not put JWT in local storage is very debatable. It's actually perfectly fine, as some comments from @Dan's article point out. If someone is able to execute malicious JS code on your website, local storage will be the least of your concerns... Please read comments to this article as the article itself doesn't do it any justice
  • user3331344
    user3331344 about 3 years
    Can you expand on why the xss/csrf attacks to the /refreshtoken endpoint will not be harmful. Don't they get the access token if they make this call.
  • itay312
    itay312 about 3 years
    The access token is stored in memory, not in a cookie or in local storage, So csrf cannot take advantage of any cookie or existing session, and the only way xss attack will work is if the attacker will know the exect location in memory where you stored the token, be smart enough to not compromise it easily and you will be fine.
  • itay312
    itay312 about 3 years
    Nowdays I am using another solution which is less painfull but secure enough. On server side I split the jwt into 2 parts. One with the payload and headers, and the other with just the signature. I store the first part in a cookie with same site flag, and the second part in an httpOnly cookie also with sameSite. When the server receives a request, it takes both cookies and reassembles the jwt and then checks fot its validation. I also send as a request header another user identifier (like the user id) and this user id is also encrypted in the jwt signature so it is another protection layer mak
  • Jivan Bhandari
    Jivan Bhandari almost 3 years
    How do you handle browser refresh if the access token is in memory? Won't user see a flash second of login page while you are still waiting for refrehsing the token
  • Dean Hiller
    Dean Hiller about 2 years
    OUCH, so you are the reason @itay312 these websites log me out when I open a new tab!!! grrrr. definitely use an xss attack protected cookie as it works cross tab AND works across browser restarts saving the user headaches and expire the cookie or JWT token or both.
  • Cazineer
    Cazineer about 2 years
    This is not recommended, as others have pointed out. Do not do this.
  • AntonB
    AntonB almost 2 years
    Cookie token does not prevent XSS. Please note that your browser on reflected XSS, stored XSS or DOM node XSS will still gladly attach cookies to requests in the event of an XSS attack.