oauth-2.0 - 重新认证不需要 JWT 刷新令牌
问题描述
到目前为止,我正在使用短期令牌和刷新令牌进行 API 身份验证。我仅使用刷新令牌来获取用户 ID 以查询数据库以检查用户的最新权限和活动/阻止状态。现在我在想,为什么我不应该从短暂的令牌本身中提取这个用户 ID。下面的函数是用来解码JWT的,在这个过期后验证签名。因此,如果我收到“过期”错误,则表示令牌签名良好且令牌未经过处理。现在我可以从过期的 JWT 中提取中间(yyy 来自 xxx.yyy.zzz)base64 编码数据来获取用户 ID。所以我不认为值得使用刷新令牌。还可以使用自定义时间戳在令牌本身中定义更长时间的访问,这样我在一个令牌中就有两个时间限制,例如 5 分钟和 90 天。你觉得呢?你有没有什么想法?
public static function decode($jwt, $key, array $allowed_algs = array())
{
$timestamp = is_null(static::$timestamp) ? time() : static::$timestamp;
if (empty($key)) {
throw new InvalidArgumentException('Key may not be empty');
}
$tks = explode('.', $jwt);
if (count($tks) != 3) {
throw new UnexpectedValueException('Wrong number of segments');
}
list($headb64, $bodyb64, $cryptob64) = $tks;
if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) {
throw new UnexpectedValueException('Invalid header encoding');
}
if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) {
throw new UnexpectedValueException('Invalid claims encoding');
}
if (false === ($sig = static::urlsafeB64Decode($cryptob64))) {
throw new UnexpectedValueException('Invalid signature encoding');
}
if (empty($header->alg)) {
throw new UnexpectedValueException('Empty algorithm');
}
if (empty(static::$supported_algs[$header->alg])) {
throw new UnexpectedValueException('Algorithm not supported');
}
if (!in_array($header->alg, $allowed_algs)) {
throw new UnexpectedValueException('Algorithm not allowed');
}
if (is_array($key) || $key instanceof \ArrayAccess) {
if (isset($header->kid)) {
if (!isset($key[$header->kid])) {
throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key');
}
$key = $key[$header->kid];
} else {
throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
}
}
// Check the signature
if (!static::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
throw new SignatureInvalidException('Signature verification failed');
}
// Check the nbf if it is defined. This is the time that the
// token can actually be used. If it's not yet that time, abort.
if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
);
}
// Check that this token has been created before 'now'. This prevents
// using tokens that have been created for later use (and haven't
// correctly used the nbf claim).
if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
);
}
// Check if this token has expired.
if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
throw new ExpiredException('Expired token');
}
return $payload;
}
解决方案
不要这样做。你的计划打破了惯例。它也违反了 OAuth 标准。新开发人员会认为这是一个错误。您的公司可能会聘请安全审计员,该人员将使用过期令牌测试访问权限。这将被报告为您必须修复的问题。
推荐阅读
- android - 单击工具栏中的搜索按钮后视图未正确显示
- google-cloud-functions - 带有 pub sub 触发器的云功能不适用于跨区域
- javascript - 如何在 Javascript 中获取上一个日期?
- php - 如何根据不同的变量保存变量?
- jquery - $ 不是函数 - 嵌套函数
- c# - 有没有办法“加载”浏览器但不显示任何内容?头孢夏普
- html - 如何消除对表单字段的关注
- android - FirebasePerformance:方法跟踪(使用 @AddTrace)不显示在 Logcat 中
- sql - 根据另一行填充行(将价格从分支 0 复制到所有其他分支)
- python - 将对象方法作为函数参数传递给python中的方法链接