DEV Community

Margaret W.N
Margaret W.N

Posted on

Generating a Json Web Token

What's a token?

I'd describe it as a uniquely generated code that identifies an authenticated user in a system.

Why do we need a token?

Imagine a scenario where a user had to constantly re-enter their credentials to perform an action on the system, It would be annoyingly tedious! A better alternative is to assign a token to a user, which gives the user the permission to perform necessary actions for as long as the token is valid.

How do we generate one?

We use JWT: Its a standard that provides a trusted mechanism for secure transfer of data between parties. You can read more on this Here
We npm install jsonwebtoken the include the dependency in our file (i'm working on userController.js)

const jwt = require('jsonwebtoken');
Enter fullscreen mode Exit fullscreen mode

If the password is verified a random number will be generated using crypto. Crypto is a node module hence we need not to install.

 const secret = require('crypto').randomBytes(48).toString('hex');
Enter fullscreen mode Exit fullscreen mode

Randombytes generates a set of random numbers while .toString() converts the numbers to a string.

Next we'll create a token using jwt:

const token = jwt.sign({ id: user._id }, secret, {
        expiresIn: 86400 
      });
      return res.json({token});
Enter fullscreen mode Exit fullscreen mode

Jwt takes an user object that's a unique identifier, a secret key which is our random number, a callback function or an option such as expiresIn which sets the expiry time of the token. I'm returning the token to verify its working.

Here is the full code;

const userLogin = (req, res) => {
  User.findOne({ email: req.body.email }, async (err, user) => {
    if (err) {
      return res.send(err);
    }
    if (await bcrypt.compare(req.body.password, user.password)) {

      const secret = require('crypto').randomBytes(48).toString('hex');

      const token = jwt.sign({ id: user._id }, secret, {
        expiresIn: 86400 
      });
      return res.json({token});
      // return res.send(`Welcome back   ${user.firstName}`)
    }
    return res.send('Wrong Password');
  })
}
Enter fullscreen mode Exit fullscreen mode

I'll head over to postman and test my 'user/login' route. It should send back a token:
Alt Text
Seems to be working okay.

Day 30, look who made it this far!!!🥳🥳🥳

Top comments (4)

Collapse
 
nathanbarrett profile image
Nathan Barrett

great topic to cover! however what you actually want to send back to the user after login is just the jwt secret (which you also store attached to the user). the client (browser) code then uses jwt.sign to create tokens that get sent through the Authorization header and looks something like "Authorization: Bearer {token_here}". Auth protected endpoints on your end would inspect the authorization header and run jwt.verify to make sure that the token matches the jwt secret of the user. if so proceed. if not return 401 Unauthorized.

Collapse
 
mtee profile image
Margaret W.N

Does that mean i do not have to write code to create the tokens, or where that piece of code be written?

Collapse
 
nathanbarrett profile image
Nathan Barrett

that is correct. on the server side (express js side), it's job is to verify the tokens being sent in the request to authorize the user. so express js auth middleware will most likely use jwt.verify . in your browser code, before making the request is where jwt.sign would be used to create a token that gets put inside of the request that is verified by your express js api. so when the user logs in you send them their jwt "secret". so express js and the user with the browser both have the secret. the user uses that secret to create jwt tokens. express js checks to see if that token is valid using the secret as well. I also forgot to mention that there should be another header field where they specify which account they are authorizing as. For me, I have used another header field called "Account" where their email is inserted. If you like I could create a fork from your code base and put together a quick example with an explainer. just let me know. keep up the great work!!

Thread Thread
 
mtee profile image
Margaret W.N

Okay, I'd greatly appreciate that. It's pretty confusing for me here is the link to the repo github.com/M-Tee/SCAMP-Assesment