Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How much information should go in a JWT payload?

I'm building a flashcard app with the Mean stack and trying to mimic the process followed in this tutorial https://thinkster.io/mean-stack-tutorial#wiring-everything-up .

When a new user registers I want to return that user's information in a user object: the current and most recent deck of flashcards being studied, the current and most recent card being studied, etc.

My question is how much of this information should go into the JWT payload?

In the thinkster.io tutorial the payload of the JWT contains only the user_ID, username, and expiration date. I worry if the extra information shouldn't go into the JWT because it would make the JWT too big. Then do I just send the JWT back along with a user object which is returned after the user is saved with the mongoose.save method? This strategy sounds like it matches the following quote from:

https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies/#token-size

Every time you make an API request you have to send the token in the Authorization header.

Depending on how much information you store in that token, it could get big. On the other hand, session cookies usually are just an identifier (connect.sid, PHPSESSID, etc.) and the rest of the content lives on the server (in memory if you just have one server or a database if you run on a server farm).

Now, nothing prevents you from implementing a similar mechanism with tokens. The token would have the basic information needed and on the server side you would enrich it with more data on every API call. This is exactly the same thing cookies will do, with the difference that you have the additional benefit that this is now a conscious decision, you have full control, and is part of your code.

The /register route code I'm trying to mimic from thinkster.io is the following:

router.post('/register', function(req, res, next){
  if(!req.body.username || !req.body.password){
    return res.status(400).json({message: 'Please fill out all fields'});
  }

  var user = new User();

  user.username = req.body.username;

  user.setPassword(req.body.password)

  user.save(function (err){
    if(err){ return next(err); }

    return res.json({token: user.generateJWT()})
  });
});

Could I just edit the save method part at the bottom to look something like this:

user.save(function (err, user){
    if(err){ return next(err); }

    return res.json({token: user.generateJWT(), 
                     user: user})
  });

Or should all of the extra user information be put into the JWT and only the JWT gets passed back?

like image 468
DC1477 Avatar asked Nov 10 '22 02:11

DC1477


1 Answers

You need to use according to your need of security.

For my applications, for example, I do follow your example. The token is stored in the client cookie and, within authentication, I do one thing:

  • Decode JWT and populate request.user with _id and another primary key.
  • Send back the token and the user info.

The same user info can be exposed in an API call. One important thing to notice is that my system do not need to be always updated and syncronized. So, my client user will only fetch user data when login in is made and on a specific GET request.

You don't need to mix a lot of garbage in your JWT. It need to be decoded yet.

like image 123
Rodmentou Avatar answered Nov 15 '22 05:11

Rodmentou