Search code examples
reactjsnode.jscookiesjwtmern

How to log out and clear cookies after jsonwebtoken expires?


Since the lifetime of JWT token is 15 seconds, I want to clear the cookie after that time. But I don't know how to do it properly. Does it need to be done on the server side or can it be done on the client side? Code with description below

Using mongoose I create a user model and add a JWT token to it.

const mongoose = require('mongoose');
const jwt = require('jsonwebtoken');

const userSchema = new mongoose.Schema({
  email: { type: String, required: true },
  password: { type: String, required: true },
});

userSchema.methods.generateAuthToken = function() {
  const token = jwt.sign({ _id: this._id }, process.env.JWTPRIVATEKEY, {expiresIn: "15s"})
  return token
};

const User = mongoose.model('users', userSchema);

module.exports = { User }

const router = require('express').Router();
const { User } = require('../models/User');

router.post('/', async (req, res) => {
  try {
    const user = await User.findOne({ email: req.body.email });

    const token = user.generateAuthToken();
    res.status(200).send({ data: token, message: "Logging in is successful" });
  } catch (error) {
    console.log(error);
    res.status(500).send({ message: 'Internal Server Error' })
  }
});

data: token This is the key issued by JWT. Recall that this is the JWT token that is created when a user is created. See the previous code


Next is a simple form where I make a request and receive a token in response, which I store in cookies

import { Cookies } from "react-cookie";
    
const cookies = new Cookies();
    
const handleChange = ({ currentTarget: input }) => {
  setData({ ...data, [input.name]: input.value });
};
    
const handleSubmit = async (event) => {
  event.preventDefault();
   try {
     const url = "http://localhost:8080/api/auth";
     const { data: res } = await axios.post(url, data);
     cookies.set('token', res.data);
   } catch (error) {}
       
<form onSubmit={handleSubmit}>
  <input type="email" name={"email"} value={data.email} onChange={handleChange} required placeholder={"Email"} />
  <input type="password" name={"password"} value={data.password} onChange={handleChange} required placeholder={"Password"} />
  <button type="submit">Login</button>
</form>

And this is the JWT token I mentioned above. enter image description here


Solution

  • You would check if the JWT token has expired on the client side before running any requests that need it using jwt.verify().

    jwt.verify(token, 'shhhhh', function(err, decoded) {
      if (err) {
        /*
          err = {
            name: 'TokenExpiredError',
            message: 'jwt expired',
            expiredAt: 1408621000
          }
        */
      }
    });
    

    Inside the if (err), you would handle invalidating the user’s session, such as deleting the expired token from their cookies and redirecting them to your login form.