Essay97
Essay97

Reputation: 874

JWT authentication with passport-jwt does not take expiration date into account

I am trying to do an authentication system using JWT token in Express, using passport-jwt and jsonwebtoken. Everything works well now, but even if I set an expire date the token remains valid even after that date, if I try to use it with Postman, I can't figure out what am I missing. From my understanding, and from what I saw in many tutorials, expiration date should be handled by passsport-jwt itself, but if I try to use a token generated some days ago it still works, even if I did set the duration to one day. Here's my code:

//passport.jwt.ts

const publicKey: string = process.env.PUBLIC_KEY.replace(/\\n/g, "\n");

const options = {
  jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
  secretOrKey: publicKey,
  algorithms: ["RS256"],
};

const strategy = new JWTStrategy(options, async (payload, done) => {
  const repo: UserRepository = RepoManager.getUserRepo();
  try {
    const user: UserModel = await repo.getUserById(payload.sub);
    if (user) {
      return done(null, user);
    } else {
      return done(null, false);
    }
  } catch (error) {
    done(error);
  }
});

export function JWTPassport(passport) {
  passport.use(strategy);
}

//register user middleware for the /register route
export async function registerUser(req, res) {
  try {
    const { salt, hash } = hashPassword(req.body.password);

    const newUser = {
      username: req.body.username,
      password: hash,
      salt: salt,
      email: req.body.email,
    };

    let model: UserModel = Deserialize(newUser);
    const repo: UserRepository = RepoManager.getUserRepo();
    model = await repo.createUser(model);

    const jwt = issueJWT(model);
    res.status(200).json({ user: model, jwt: jwt });
  } catch (e) {
    res
      .status(400)
      .json({ error: "could not register user" });
  }
}
//function generating the JWT token
export function issueJWT(user: UserModel) {
  const id = user.id;

  const expiresIn = "1d";

  const payload = {
    sub: id,
    iat: Date.now(),
  };

  const signedToken = sign(payload, privateKey, {
    expiresIn: expiresIn,
    algorithm: "RS256",
  });

  return {
    token: "Bearer " + signedToken,
    expires: expiresIn,
  };
}

EDIT: I figured out part of the problem, the timestamps were being generated in milliseconds instead of seconds. Now I manually calculate the timestamps with 60 * 60 * 24, but I'd like to understand why the syntax "1d" since it is recommended in the docs

Upvotes: 0

Views: 1124

Answers (2)

The same problem. The problem in iat date. Try to set iat like this:

const expiresIn = "20s";

const payload = {
  sub: id,
  iat: Math.floor(Date.now() / 1000),
};

const signedToken = jsonwebtoken.sign(payload, ACCESS_TOKEN_PRIV_KEY, {
  expiresIn: expiresIn,
  algorithm: "RS256",
});

Upvotes: 2

Sarah
Sarah

Reputation: 81

Try this in issue Jwt

const signedToken = jwt.sign(payload, privateKey, {
    expiresIn: "1h",  
    algorithm: "RS256",
  });

Upvotes: 0

Related Questions