30
votes

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

3
If you store the token in localstorage, that should be all you need. Same with any app, not just reactazium
waouh, thanks for your fast answer. How can I achieve that ? and by localstorage is it built in express so I can call this method ..?MaieonBrix
localstorage is a browser thing. when you send the token from express to your client, save the token inlo storage just by doing localStorage.token = token. Then when you make subsequent requests to your server send the token that saved from localstorage. react router docs have an example of exactly this github.com/reactjs/react-router/tree/master/examples/auth-flowazium

3 Answers

29
votes

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.

14
votes

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.

2
votes

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.