DEV Community

Cover image for Simple auth system using JWT
Luthfi Khusyasy
Luthfi Khusyasy

Posted on

Simple auth system using JWT

Continuation of the last post, I will try to implement auth system by using JWT (Json Web Token) for my Multiplayer TicTacToe game.

Live Website
Source Code

What is JWT

JWT is an authorization token created from the backend, passed to the frontend and then the frontend can send this token alongside requests to access protected API routes, it is to make sure that the request from user X is indeed made by user X itself. Usually JWT token is created with expiration time.

There is a downside here for using JWT, every token that was created and not yet expired can still be used for accessing the protected API routes. Which is usually not what you wanted.

Little disclaimer here: I think JWT itself is actually very simple, but implementing it the right way is the hard part, so if you know a better way or have a correction, please let me know! thanks.

JWT Revoke Method

So to invalidate and limit the access of the token, from what I have found is mainly 2 methods:

  1. Blacklist/Whitelist the token.
  2. Use per user secret key for the token.

To be honest I still don't know the pros/cons of those methods, but I'm going to use the second one.

Creating User Personal Key

note: all of the examples shown are simplified version

const bcrypt = require('bcrypt');

function generatePersonalKey() {
  return bcrypt.genSaltSync(10);
Enter fullscreen mode Exit fullscreen mode

First the personal key, we need to create a function to generate the keys, like random strings, numbers, or anything. But here I created generatePersonalKey() by using the bcrypt packages to create a random salt.

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
  username: String,
  password: String,
  personalKey: String,
Enter fullscreen mode Exit fullscreen mode

And for example my UserSchema (mongoose), we just initialize the personalKey when the user is created. And when user logged out we just regenerate the personalKey, this way the tokens before will always be invalid because they used the different key.

Creating JWT

const jwt = require('jsonwebtoken');

const payload = { username: 'khusyasy' };
const token =
  jwt.sign(payload, user.personalKey, {
    expiresIn: '1h',
Enter fullscreen mode Exit fullscreen mode

To create the token itself I used jsonwebtoken packages. It is actually very simple like the example above. After that we set the response cookies with the flag httpOnly so the token cannot be set/get by using javascript on the browser.

Checking Authorization

When I first read about this I'm very confused, how do you know which key to use, if you can't even read the token?

Well it turns out we can... just by using decode to read the payload and getting the user personalKey, and then using the personalKey to verify the token itself. For example:

const payload = jwt.decode(token);

const user = await User.findOne({ username: payload.username });

try {
  const verified = jwt.verify(token, user.personalKey);
  // token is verified
} catch (err) {
  // token is invalid
Enter fullscreen mode Exit fullscreen mode

That is all for today, thank you for reading!

packages used:

Top comments (0)