6

i want to use json web tokens for validating user and i am about to use jwt.sign method, but "payload" term confused me according to wikipedia payload definition (in computing) is:

In computing and telecommunications, the payload is the part of transmitted data that is the actual intended message. Headers and metadata are sent only to enable payload delivery.[1][2]

but according to medium code

    const jwt = require('jsonwebtoken');
app.post('/api/authenticate', function(req, res) {
  const { email, password } = req.body;
  User.findOne({ email }, function(err, user) {
    if (err) {
      console.error(err);
      res.status(500)
        .json({
        error: 'Internal error please try again'
      });
    } else if (!user) {
      res.status(401)
        .json({
         error: 'Incorrect email or password'
        });
    } else {
      user.isCorrectPassword(password, function(err, same) {
        if (err) {
          res.status(500)
            .json({
              error: 'Internal error please try again'
          });
        } else if (!same) {
          res.status(401)
            .json({
              error: 'Incorrect email or password'
          });
        } else {
          // Issue token
          const payload = { email };
          const token = jwt.sign(payload, secret, {
            expiresIn: '1h'
          });
          res.cookie('token', token, { httpOnly: true })
            .sendStatus(200);
        }
      });
    }
  });
});

payload is user provided email for authentication, that confused me, i will be glad if anyone explain what is payload and what is role of payload in jwt.sign()

ilia
  • 339
  • 8
  • 23

1 Answers1

10

In JSON Web Tokens, the payload is a set of fields that you want to include in the token being generated; Things your API will need to, say, get the right data for a particular user.

It's just a simple JSON object that is usually used to include user identification details such as a user ID, account ID or an email address. However, it can also contain any arbitrary data you might need such as a user's full name, language preferences, etc.

An example payload might look like the following, assuming these were the fields your API depended on to get details about the user/account who the token belongs to. Note that would be considered a rather large payload; Most payloads only have a single user ID field since that's typically all the endpoint should need to properly identify a user.

{
  user_id: 303,
  account_id: 909,
  email: 'joe@example.com',
  full_name: 'Joe Blow',
  default_language: 'en_US'
}

WARNING: The payload is NOT encrypted so make sure you do not store things like passwords, secret keys, credit card numbers, bank account balances, etc. in it. Only identifiers like IDs you'd see in a URL or public keys should ever be stored.

Additionally, the payload contributes to the overall length of the token (more data means longer tokens) so you only want to include the most essential pieces of data. Otherwise, you'll be sending a very large token on every request which consumes bandwidth and, theoretically, takes up more server resources to decode.

Finally, JWT are stateless, meaning they aren't sessions. So don't include any data that changes frequently, such as a game scores, last sign in, etc.

Soviut
  • 88,194
  • 49
  • 192
  • 260
  • it must be user identifier or it can be anything for example random string ? – ilia Mar 08 '19 at 19:49
  • @Jake it can be whatever you want. See my example that I've added with the user's `full_name`. – Soviut Mar 08 '19 at 19:50
  • should i include this kind of data? – ilia Mar 08 '19 at 19:54
  • 1
    @Jake again, I've addressed this in the answer. You should include the bare minimum of information needed to properly identify a user in your API, nothing more. Most JWT include a user ID and that's it. – Soviut Mar 08 '19 at 19:56
  • ah. understood, i am using unique usernames so it would be enough i think – ilia Mar 08 '19 at 19:57
  • @Jake if the user name can be changed by the user then that is not a good identifier. – Soviut Mar 08 '19 at 21:07
  • what about user._id? – ilia Mar 09 '19 at 12:15
  • would not it be a vulnerability? or should i declare another field (in db (mongo)) like id with auto implementation and use that – ilia Mar 09 '19 at 12:16
  • @Jake As I said in my answer, the user ID (in your case, the user document ID) is fine to store in a JWT. It is not a vulnerability just like knowing the user name is not a vulnerability; They're public. It's only if an attacker has the private identification info like a password or private key that there is a vulnerability. – Soviut Mar 09 '19 at 19:04