如何检测Token是否过期
除了向服务器发起请求验证token是否过期以外,一些类型的token是直接将过期时间储存在token之中的,我们可以通过这一点在客户端本地验证token是否过期。
token的构成
token其实就是三个东西以小数点分隔开的字符串
例如:
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuYXV0aDAuY29tLyIsImF1ZCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tL2NhbGFuZGFyL3YxLyIsInN1YiI6InVzcl8xMjMiLCJpYXQiOjE0NTg3ODU3OTYsImV4cCI6MTQ1ODg3MjE5Nn0.CA7eaHjIHz5NxeIJoFK9krqaeZrPLwmMmgI_XiQiIkQ |
你可以在上面的token中发现两个小数点,而被这两个小数点分隔的部分分别是:
1 | Header的base64.Payload的base64.Signature |
- Header中声明了token的元数据,例如使用的加密算法类型和token的类型
- Payload中包含了实际的数据,例如用户名等,这部分的信息内容可由后端开发人员自由调整
- Signature确保 JWT 未被篡改,如果 JWT 由服务器签发,服务器会用 secret 生成签名,客户端无法伪造
你其实可以随便在网上搜一个base64解码器,然后删除Signature部分进行解码,例如上述token删除Signature部分解码后的结果是:
1 | {"alg":"HS256","typ":"JWT"}{"iss":"https://example.auth0.com/","aud":"https://api.example.com/calandar/v1/","sub":"usr_123","iat":1458785796,"exp":1458872196} |
在本地检测token是否过期
在上述token拥有的数据中,payload部分的exp
字段是一个时间戳,指定了该token的过期时间
时间戳就是从1970年1月1日至今以来的秒数或毫秒数,如果时间戳是10位,那么就是秒数,13位就是毫秒数,上面的例子中,使用的是秒级时间戳
通过exp
字段,我们就能判断token什么时候过期,从而决定是否该使用refreshToken来刷新accessToken
我们可以实现一个方法来判断token是否过期(使用Dart实现,其他语言大同小异):
1 | /// token过期或者格式错误则返回true,否则返回false |