【问题标题】:JSON Web Token (JWT) : Authorization vs AuthenticationJSON Web 令牌 (JWT):授权与身份验证
【发布时间】:2018-07-01 08:51:24
【问题描述】:

JWT 术语一直困扰着我,原因有几个。 JWT 适合 Authorization 还是只适合 Authentication?

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

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

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

【问题讨论】:

标签: java json authentication jwt


【解决方案1】:

JWT 有两个用途:

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

第二部分是有趣的部分。一个 JWT 包含:

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

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

来自 jwt.io 的示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

其中包含:

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

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

【讨论】:

  • 那么这个有效载荷是否有任何标准,或者它可以是任何自定义 json?
  • 你可以做任何你想做的事,但iana.org/assignments/jwt/jwt.xhtml定义了标准的公共声明和tools.ietf.org/html/rfc7519定义了注册声明
  • 此标头之间无法修改,因为它们已编码和签名。我理解正确吗?因此,在 headers 中传输角色特定信息是安全的。瑞特??
  • 是的,为了修改内容你需要知道私钥或秘密(取决于使用的算法)。
  • 这是否意味着,我必须为不同的角色或权限生成不同的网络令牌?
【解决方案2】:

授权 JWT 可以使用特定于令牌的claims 来实现。

Json Web 令牌中打包为声明的许多其他用户信息可以预先填写在令牌中,并且稍后可以被授权服务拦截。

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

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

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

【讨论】:

  • 感谢您的回复。它帮助了我。
【解决方案3】:

JWT 适合 Authorization 还是只适合 Authentication?

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

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

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

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

您理解的其余部分没有遵循正确的顺序。实际上,缺少一个称为 Token Issuer 的部分。当且仅当身份验证过程成功并且请求者被授权时,这个人负责验证 JWT 令牌请求者并发出 JWT 令牌。然后可以通过检查签名来验证颁发的 JWT 令牌,这意味着,通过像 Identity Server 这样的令牌颁发者颁发的令牌将包含消息的哈希码,这将允许令牌的消费者仔细检查签名(哈希码)以确保在客户端-服务器之间的转换过程中,令牌未被未经授权的访问修改。然后,如果令牌是有效令牌,则下一步消费者可以提取令牌 (JWT) 声明以处理授权部分。

【讨论】:

    【解决方案4】:

    用户首先登录。一旦用户通过登录过程,或者我们说一旦用户通过身份验证,您就签署一个 jwt 令牌并将其发送给用户。这是 node.js sn-p

    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() });
       });
      }
    

    现在客户端会将其保存到 localStorage。 (为简单起见,我使用 localStorage)。在客户端,用户发送 post 请求登录并获取我上面发送的内容。它将获取令牌并保存它。因为是异步请求,所以会是这样。这是一个小反应代码来演示:

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

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

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

    一旦你的服务器收到请求,你检查传入的令牌,如果它是一个有效的令牌,你将授权用户访问某些路由或服务。所以用户将被授权。

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

    【讨论】:

      猜你喜欢
      • 2018-05-07
      • 2018-01-20
      • 2017-12-10
      • 1970-01-01
      • 2019-09-23
      • 2016-01-02
      • 1970-01-01
      • 2019-10-14
      • 2014-11-18
      相关资源
      最近更新 更多