JSON Web Token (JWT):授权与身份验证



JWT术语一直困扰着我有几个原因。JWT 是否适合授权或仅用于身份验证?

如果我错了,请纠正我,但我一直将授权视为允许某人访问资源的行为,但 JWT 似乎没有任何实际允许用户访问给定资源的实现。所有 JWT 实现都谈论的是为用户提供令牌。然后,每次调用后端服务终结点时都会传递此令牌,在该终结点中检查其有效性以及是否授予了有效访问权限。因此,我们可以使用JWT对任何用户进行身份验证,但是我们如何限制对特定有效用户的访问?

我们如何使用 JWT 根据他们拥有的角色限制少数用户? JWT是否也提供任何类型的授权详细信息,还是仅向我们提供身份验证?

提前感谢您的帮助,并耐心阅读我的疑问。

可以使用令牌特定的声明实现JWT的授权

Json Web令牌中打包为声明的许多其他用户信息一样,特定权限可以预先填充在令牌中,以后可以通过授权服务截获。

通常,授权将基于权限,其中权限用于限制对 api 终结点的访问(也可用于授予用户对前端应用视图的访问权限)。

下面是一个具有权限元素的示例JWT令牌:

{
"UserInfo": {
"id": "#{USER_ID}",
"roles": {
"#{ROLE_NAME}": "#{ROLE_ID}"
},
"permissions": {
"#{PERMISSION_NAME}": "#{PERMISSION_ID}",
}
},
"exp": 1488888888
}

JWT 可用于两个目的:

  1. 身份验证(如您所说)
  2. 信息交流。

第二部分很有趣。JWT 包含:

  • 标头:包含算法和令牌类型
  • 有效负载:是关于实体(通常是用户)和其他元数据的语句。有三种类型的声明:已注册、公共和私人声明。
  • 签名:签名用于验证 JWT 的发件人是否是它所说的人,并确保消息在此过程中未被更改。

有效负载可以包含有关用户的信息,例如权限列表。 这样,您可以将其用于授权。

jwt.io 的例子:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

其中包含:

{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

您可以看到有效负载包含有关管理权限的身份和信息。由于有效负载签名,您可以信任这些数据。

用户首先登录。一旦用户通过登录过程,或者我们说一旦用户通过身份验证,您就会签署 jwt 令牌并将其发送给用户。这是节点.js片段

async postLogin(req, res, next) {
// parse the req.body, get the email,password
// check if the email exist, if exists check the passord
// now you are sure credentials are true, create the jwt.
const token = jwt.sign({ _id: this._id, email: this.email }, "this-is-secret", {
expiresIn: "1h",
res
.status(200)
.header("x-auth-token", token)
.json({ token, userId: existingUser._id.toString() });
});
}

现在客户端将把它保存到本地存储。(为简单起见,我使用本地存储)。在客户端,用户发送 post 请求登录并获取我上面发送的内容。它将获取令牌并保存它。由于它是异步请求,因此它将是这样的。这是一个小的 react 代码来演示:

.then(resData => {
localStorage.setItem('token', resData.token);
localStorage.setItem('userId', resData.userId);

关于令牌的一件事,浏览器不会自动发送它,因此客户端会手动将其附加到请求中。

fetch(url, {
method: "post",
headers: {
Authorization: 'Bearer ' + localStorage.getItem('token')
}
})

服务器收到请求后,检查传入令牌,如果它是有效的令牌,您将授权用户访问某些路由或服务。因此,用户将被授权。

身份验证是识别用户并验证他们声称是谁的过程。验证身份的最常见和最明显的因素之一是密码。如果用户名与密码凭据匹配,则表示身份有效,并且系统向用户授予访问权限,因此我们说用户已通过身份验证

JWT 是否适合授权或仅用于身份验证?

这个问题的答案就在RFC7519标准的以下几行中:

JSON Web 令牌 (JWT) 是一种紧凑的声明表示格式 适用于空间受限的环境,如 HTTP 授权标头和 URI 查询参数。

JWT 似乎没有任何实际允许用户访问给定资源的实现。

我会说你理解的这一部分需要一些润色;-) 事实上,JWT 有一个称为声明的结构,您可以在其中找到与授权相关的主题。

你理解的其余部分没有遵循正确的顺序。事实上,有一个缺失的部分叫做令牌发行者。这家伙负责对 JWT 令牌请求者进行身份验证,并在身份验证过程成功且请求者获得授权时颁发 JWT 令牌。然后,可以通过检查签名来验证颁发的 JWT 令牌,这意味着,通过令牌颁发者(如身份服务器)颁发的令牌将包含消息的哈希代码,这将允许令牌的使用者仔细检查签名(哈希代码),以确保在客户端-服务器之间的转换期间未通过未经授权的访问修改令牌。然后,如果令牌是有效令牌,则下一步的使用者可以提取令牌 (JWT) 声明来处理授权部分。

最新更新