Bearer 用于身份验证令牌,但用于不同的令牌?

Posted

技术标签:

【中文标题】Bearer 用于身份验证令牌,但用于不同的令牌?【英文标题】:bearer is for the authentication token but is for a different token? 【发布时间】:2020-10-15 02:14:18 【问题描述】:

对于我的 MEVN 应用程序,我正在使用 jwt 令牌,并且正在学习如何通过 axios 发送身份验证令牌。有人告诉我,将“Bearer”放在令牌之前并让“Bearer”的服务器切片来读取令牌的正文是标准做法。但是如果我有 2 个令牌呢?第一个令牌用于用户,而第二个令牌用于管理应用程序的特殊帐户。为了让生活变得简单,我在我的应用程序中编写了 2 个用户系统。 1个用于普通用户,另一个用于管理员。我在管理员帐户令牌前面放了什么?

传递给服务器的示例 jwt 令牌字符串:

Bearer cdsklfj2...

【问题讨论】:

【参考方案1】:

Authorization header中的Bearer只是告诉服务器它是一个API令牌,它与用户的权限或它是哪个用户无关。

要区分用户角色,您可以将角色放在您的 JWT 负载上。例如,如果您decode this token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywicm9sZXMiOlsiQURNSU4iLCJOT1JNQUxfVVNFUiJdfQ.u0YXpuJkQ08RBb4_s6yVeGT3Ua21ptUbXvrzopG-txI

您会看到它在负载中包含userIdroles,其中userId 是该令牌的用户ID,roles 是用户拥有的权限。

因此,在您的 express 应用上,您可以执行以下操作:

try 
    const payload = verifyToken(jwtToken);
 catch (err) 
    // assuming if the verification failed because of invalid token will throw an error
    return res.status(401).send(); // Unauthorized


// Check from roles array if it has "ADMIN" in it
if ( payload.roles.includes("ADMIN") ) 
    adminOnlyFunction(); // Function that can be accessed by admin only
    return res.status(200).send();
 else 
    // If user has no ADMIN roles, return 403 instead
    return res.status(403).send(); // Forbidden

但是使用这种方法有一个缺点,特别是如果 JWT 令牌长期存在,假设 userId 1 具有 ADMIN 权限,并且在令牌过期之前,您决定 userId 1 不再是管理员,userId 1 仍然能够调用adminOnlyFunction(),因为角色信息存储在 JWT 有效负载中。您可以通过在更改用户权限时将令牌列入黑名单来防止这种情况发生。

我个人不会把roles放在JWT的payload里,而是把用户的角色信息存储在你的数据库中,每次用户向你的服务器发送请求时检查角色,你可以阅读this answer on为什么你不应该在你的 JWT 上设置角色,以及更好的方法。最后,它始终取决于您的用例。

【讨论】:

您还可以使用类似 OAuth 中的用户信息端点:oauth.com/oauth2-servers/signing-in-with-google/…、connect2id.com/products/server/docs/api/userinfo)。因此,这些角色由您的 IAM 解决方案而非您的软件管理。您的应用需要调用它以了解用户角色/等级/任何内容(如有必要,将用户信息存储在本地存储中)。 另外,我不明白decodeJwtWithYourPrivateKey:JWT 令牌可以在没有密钥的情况下解码,它只是 base64 编码。但是如果根据私人签名,你可以验证它,它是不同的:) 但是你的框架或 IAM 应该验证它,你不必手动进行。 你是对的,verifyToken 将是更好的方法名称,已编辑。

以上是关于Bearer 用于身份验证令牌,但用于不同的令牌?的主要内容,如果未能解决你的问题,请参考以下文章

使用不记名令牌进行身份验证(≠ 授权)

谷歌帐户的不同身份验证令牌

从 ASP.NET vNext beta5 移动到 beta7 后 JWT Bearer 令牌身份验证错误

将 REST API 用于 id 令牌时对 Firebase 存储进行身份验证

如何在 Spring Boot 应用程序上启用 Bearer 身份验证?

用于用户身份验证的个人访问令牌和 json Web 令牌有啥区别?