关于javascript:jwt检查令牌是否过期

jwt check if token expired

我已经这样配置了令牌:

1
2
3
4
5
6
7
8
9
jwt.sign(
  {
    user: pick(user, ['_id', 'username'])
  },
  secret,
  {
    expiresIn: '2m'
  }
);

但是当我想检查令牌是否已过期时,此代码不起作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function isAuthenticated() {
  const token = localStorage.getItem('token');
  const refreshToken = localStorage.getItem('refreshToken');
  try {
    decode(token);
    const { exp } = decode(refreshToken);
    if (exp < (new Date().getTime() + 1) / 1000) {
      return false;
    }
  } catch (err) {
    return false;
  }
  return true;
}

问题是这部分:

1
2
3
if (exp < (new Date().getTime() + 1) / 1000) {
  return false;
}

new Date()。getTime()1)/ 1000 = 1531335468.113

exp = 1531334595

因为我不知道JWT使用哪种时间格式...

我该如何解决?

谢谢!


如果有人想知道,这就是答案

1
2
3
if (Date.now() >= exp * 1000) {
  return false;
}


您应该使用jwt.verify,它将检查令牌是否已过期。
如果源不受信任,则不应使用jwt.decode,因为它不会检查令牌是否有效。


verify本身如果过期则返回错误。如@Gabriel所说的,更安全。

1
2
3
4
5
6
7
8
9
10
const jwt = require('jsonwebtoken')

router.use((req, res, next) => {
  const token = yourJwtService.getToken(req) // Get your token from the request
  jwt.verify(token, req.app.get('your-secret'), function(err, decoded) {
    if (err) throw new Error(err) // Manage different errors here (Expired, untrusted...)
    req.auth = decoded // If no error, token info is returned in 'decoded'
    next()
  });
})

async/await语法相同:

1
2
3
4
5
6
7
8
9
10
11
12
const jwt = require('jsonwebtoken')
const jwtVerifyAsync = util.promisify(jwt.verify);

router.use(async (req, res, next) => {
  const token = yourJwtService.getToken(req) // Get your token from the request
  try {
    req.auth = await jwtVerifyAsync(token, req.app.get('your-secret')) // If no error, token info is returned
  } catch (err) {
    throw new Error(err) // Manage different errors here (Expired, untrusted...)
  }
  next()
});

可悲的是,@AndrésMontoya的答案有一个缺陷,与他比较obj的方式有关。我在这里找到了应该解决此问题的解决方案:

1
2
3
4
5
6
7
8
const now = Date.now().valueOf() / 1000

if (typeof decoded.exp !== 'undefined' && decoded.exp < now) {
    throw new Error(`token expired: ${JSON.stringify(decoded)}`)
}
if (typeof decoded.nbf !== 'undefined' && decoded.nbf > now) {
    throw new Error(`token expired: ${JSON.stringify(decoded)}`)
}

感谢约翰·弗里德曼!


您可以使用jwt verify方法来检查令牌的有效性。错误表示令牌已过期,并且会引发错误,因此您可以删除存储的令牌。

1
2
3
4
5
 jwt.verify(token, SECRET, (err, decoded) => {
      if (err) {
          localStorage.clear();
      }}
  });

这是react-native的,但登录将适用于所有类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
isTokenExpired = async () => {
    try {
        const LoginTokenValue = await AsyncStorage.getItem('LoginTokenValue');
        if (JSON.parse(LoginTokenValue).RememberMe) {
            const { exp } = JwtDecode(LoginTokenValue);
            if (exp < (new Date().getTime() + 1) / 1000) {
                this.handleSetTimeout();
                return false;
            } else {
                //Navigate inside the application
                return true;
            }
        } else {
            //Navigate to the login page
        }
    } catch (err) {
        console.log('Spalsh -> isTokenExpired -> err', err);
        //Navigate to the login page
        return false;
    }
}


1
2
3
4
5
6
7
8
// Pass in function expiration date to check token
function checkToken(exp) {
    if (Date.now() <= exp * 1000) {
      console.log(true, 'token is not expired')
    } else {
      console.log(false, 'token is expired')
    }
  }