Home > Software engineering >  Logout all users with the same JWT token
Logout all users with the same JWT token

Time:01-23

I am working with React and Nodejs. I am using JWT for the auth mechanism. Now there is a case where multiple users are logged in with the same email say "[email protected]".

Now we want to implement "Logout from all devices" which should expire all the tokens and throw the users out of their devices.

What could be the best approach to do that?

CodePudding user response:

I let you here 2 different ways you can do that, maybe are more but this 2 are good . 1-You can create a new field to the mongo db user document called: jwt_validDate, it stores the Date from when the jwt should be valid. Also, when u authorize is a valid jwt you should check if the creation time date of jwt is recent than the users fields jwt_validDate, if the jwt is recent than the validation date , its okay but if the jwt is older than the validation date return a response error saying that the jwt expired and that the gmail account must login again. Thats a good scalable way of do that, 2-else another way is set a new mongodb document field with an array [] of jwt valid tokens, there you store all jwt valid token, and when you want to logout everyone just remove the jwt valid tokens from the array. For do that you should also implement the auhtorization method that checks if the jwt token trying to login is in the array.

CodePudding user response:

When you generate the JWT, you can make use of a guid which represents some kind of a unique "device id", which gets also stored on the server side with a reference to the user like the user id.

During the verification of the JWT, you just have to check if the guid is still present on the db, if not tell the client to sign in again.

With this, you have the possibility to remove everything from the stored table where the user id matches and sign out all clients at once.

I would also suggest to use a 2nd unique identifier inside the payload as described here to increase the security even further.

And if you store/update additional informations on any activity of the client, like the user-agent and the current timestamp, you can also provide a listt on which device the client was active lately and let him sign out from a specific device on it's own if needed.

For example:

Login:

// after validation of user/password

let config = { expiresIn: "2 days", issuer: "example" };
let payload = {
  ...otherData, // other stuff needed on the client side like the username to display somewhere
  guid: uuid.v4(),
  refTokID: uuid.v4()
}
let token = jwt.sign(payload, SECRET, config);
let decoded = jwt.verify(token, SECRET);

/*
 * store payload.guid, payload.refTokID, user.id 
 * and expiration date (decoded.exp) from the token to db
 * ( optional with current timestamp & user agent)
 *
 * where the expiration date is used as a info for a
 * cronjob to delete expired tokens automatical in
 * intervals (daily, hourly, whatever)
 */

// send token to client

Verification:

try {
  let decoded = jwt.verify(token, SECRET);

  // get user id and user data (left join) from db where guid and refTokID matches

  if (found) { 
    // other logic like, check if user is still active/not locked and so on

  /*
   * check db if the guid with the given refresh for the given user is still present
   *
   * (optional) If ok, just update the User Agent info and access time and continue
   *
   * If not, send a HTTP 401 Unauthorized Error or whatever you like to tell the client,
   * that the token is not valid anymore and that he has to sign in again
   */
  } else {
    // 401 
  }
} catch(e) {
  // 500
}

Renewal:

// assuming the token is already decoded and verified.

// generate new token but use the same guid,
let token = jwt.sign({ 
  ...otherData,
  guid: decoded.guid,
  refTokID: uuid.v4() // generate a new refresh token to invalidate the old JWT directly
}, SECRET, config);

// update expiration date and refresh token where guid and decoded.refTokId matches at the db

// send the new token to client
  • Related