Code前端首页关于Code前端联系我们

如何使用widget获取AccessToken?

terry 2年前 (2023-09-22) 阅读数 78 #移动小程序
作者:demo007x

AccessToken

访问令牌是应用程序用来代表用户发出 API 请求的令牌。访问令牌表示对特定应用程序访问用户数据的特定部分的授权。

访问令牌不需要采用任何特定格式,尽管不同的选项有不同的考虑因素,这将在本章后面讨论。就客户端应用程序而言,访问令牌是一个不透明的字符串,它将接受任何字符串并在 HTTP 请求中使用它。资源服务器需要了解访问令牌的含义以及如何验证它,但应用程序永远不会关心理解访问令牌的含义。

访问令牌在传输和存储过程中必须保密。唯一需要查看访问令牌的各方是应用程序本身、授权服务器和资源服务器。应用程序应确保同一设备上的其他应用程序无法访问访问令牌的存储。访问令牌只能通过 HTTPS 连接使用,因为通过未加密的通道发送它很简单。

令牌端点是应用程序请求获取用户访问令牌的位置。本节介绍如何验证令牌请求并返回适当的响应和错误。

授权代码请求

当应用程序与访问令牌交换授权代码时使用授权代码。用户通过重定向 URL 返回应用程序后,应用程序从 URL 检索授权代码并使用它来请求访问令牌。该请求将被发送到令牌端点。

请求参数

访问令牌请求将包含以下参数。

grant_type(必填)

参数grant_type必须设置为“授权码”。

code(必填)

该参数是客户端之前从授权服务器收到的授权码。

redirect_uri(可能是必需的)

如果重定向 URI 包含在原始身份验证请求中,则服务还必须在令牌请求中要求它。令牌请求中的重定向 URI 必须与生成授权代码时使用的重定向 URI 完全匹配。否则,服务必须拒绝该请求。

code_verifier(需要 PKCE 支持)

如果客户端 code_challenge 在原始代码授权请求中包含参数,则现在必须在 POST 中包含 POST 验证请求。生成哈希值背后的秘密。这是用于计算先前在 code_challenge 参数中发送的哈希值的明文字符串。

client_id(如果没有其他客户端身份验证,则需要)

如果客户端通过 HTTP Basic Auth 或其他方法进行身份验证,则不需要此参数。否则,该参数是必需的。

如果向客户端发出客户端密钥,服务器必须对客户端进行身份验证。对客户端进行身份验证的一种方法是接受此请求中的另一个参数,client_secret。或者,授权服务器可以使用 HTTP 基本身份验证。从技术上讲,该规范允许授权服务器支持任何类型的客户端身份验证,并提到公钥/私钥对作为一个选项。事实上,大多数消费者服务器都支持使用此处提到的一种或两种方法对客户端进行身份验证的更简单方法。有关对客户端进行身份验证的更高级方法,请参阅 RFC 7523,其中定义了使用签名 JWT 作为客户端身份验证的方法。

确认身份验证代码分配

检查所有必要的参数并验证客户端(如果客户端已获得凭据)后,身份验证服务器可以继续验证请求的其他部分。

服务器随后检查授权码是否有效且未过期。然后,服务必须验证请求中指定的授权代码是否已发送给所识别的客户端。最后,服务必须确保当前的重定向 URI 参数与用于请求授权代码的重定向 URI 匹配。

对于 PKCE 支持,身份验证服务器必须计算此令牌请求中提供的 SHA256 哈希值 code_verifier,并将其与 授权请求code_ 中提供的值进行比较c.如果它们匹配,则身份验证服务器可以确定发出令牌请求的客户端与发出原始身份验证请求的客户端是同一客户端。

如果一切正常,服务可以生成访问令牌并做出响应。

安全注意事项

防止重放攻击

如果授权码被多次使用,认证服务器必须拒绝后续请求。如果授权代码存储在数据库中,那么这很容易实现,因为它们可以简单地标记为已使用。

如果您实施自编码授权代码(如我们的示例代码所示),您必须跟踪在其生命周期内花费的令牌。实现此目的的一种方法是将代码在其生命周期内缓存在缓存中。这样,在验证代码时,我们可以首先通过检查代码的缓存来检查它们是否已被使用。当代码到达过期日期时,它不再在缓存中,但我们仍然可以根据过期日期拒绝它。

如果多次使用该代码,则应视为攻击。如果可能,服务应撤销先前从此授权代码发出的访问令牌。

密码授予 密码授予

当应用程序用用户名和密码交换访问令牌时,将使用密码授予。这正是创建 OAuth 的目的,因此您永远不应该允许第三方应用程序使用此身份验证。

对密码身份验证的支持非常有限,因为无法在此过程中添加多重身份验证,并且检测暴力攻击的能力更加有限。实际中不应使用此过程。

最新的 OAuth 2.0 安全最佳当前实践规范实际上建议完全不要使用密码身份验证,并将在 OAuth 2.1 更新中将其删除。

请求参数

访问令牌请求将包含以下参数。

  • grant_type(必需) – 参数grant_type 必须设置为“密码”。
  • 用户名(必填)– 用户的用户名。
  • 密码(必填) – 用户密码。
  • 范围(可选)- 应用程序请求的范围。
  • 客户端身份验证(如果为客户端分配了机密,则需要)

如果向客户端发出机密,则客户端必须对请求进行身份验证。通常,服务将允许附加请求参数 client_idclient_secret 或接受 HTTP 基本身份验证标头中的客户端 ID 和密码。

客户端凭据 客户端凭据

客户端凭据 当应用程序请求访问令牌来访问其自己的资源而不是代表用户时,将使用授权。

请求参数

grant_type(必填)

grant_type

  • 范围(选修)

    您的服务可以支持分配客户端凭据的不同范围。事实上,真正支持这一点的服务并不多。

    客户端身份验证(必需)

    客户端必须对此请求进行身份验证。通常,服务将允许附加请求参数 client_idclient_secret 或接受 HTTP 基本身份验证标头中的客户端 ID 和密码。

    示例

    以下是服务收到的授权代码的示例。

    POST /token HTTP/1.1
    Host: authorization-server.com
    
    grant_type=client_credentials
    &client_id=xxxxxxxxxx
    &client_secret=xxxxxxxxxx

    access-token-response 访问令牌

    成功响应

    如果访问令牌请求有效,则身份验证服务器必须生成访问令牌(以及可选的刷新令牌)并将其返回给客户端,通常与以及一些有关授权的附加属性。

    带有访问令牌的响应必须包含以下属性:

    • access_token(必需)授权服务器颁发的访问令牌字符串。
    • token_type(必需)这是令牌的类型,通常只是字符串“Bearer”。
    • expires_in(推荐)如果访问令牌过期,服务器应使用分配的访问令牌的持续时间进行响应。
    • refresh_token(可选)如果访问令牌即将过期,则返回刷新令牌非常有用,应用程序可以使用该刷新令牌来获取另一个访问令牌。但是,对于使用隐式授权颁发的令牌,无法颁发刷新令牌。
    • scope(可选)如果用户分配的范围与应用程序请求的范围相同,则此参数是可选的。如果分配的范围与请求的范围不同,例如,如果用户更改了范围,则需要此参数。

    当使用访问令牌进行响应时,服务器还必须包含额外的 Cache-Control: no-storeHTTP 标头,以确保客户端不会缓存此请求。

    例如,成功的令牌响应可能如下所示:

    HTTP/1.1 200 OK
    Content-Type: application/json
    Cache-Control: no-store
    
    {
      "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
      "token_type":"Bearer",
      "expires_in":3600,
      "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
      "scope":"create"
    }

    访问令牌

    OAuth 2.0 承载令牌的格式实际上在单独的规范 RFC 6750 中进行了描述。规格。定义的结构,以便您可以生成字符串并根据需要部署令牌。不记名令牌中的有效字符是字母数字和以下标点符号:

    不记名令牌的一个简单实现是生成随机字符串并将其与关联的用户和范围信息一起存储在数据库中,或者更高级的系统可以使用自编码令牌,其中令牌字符串本身包含所有必要的信息。

    失败的响应

    如果访问令牌请求无效,例如重定向 URL 与身份验证期间使用的 URL 不匹配,服务器必须返回错误响应。

    错误响应返回 HTTP 400 状态代码(除非另有指定),参数为 errorerror_description。参数error将始终是以下值之一。

    • invalid_request – 请求缺少参数,因此服务器无法继续处理该请求。如果请求包含不支持的参数或重复的参数,也可能返回此信息。
    • invalid_client – 客户端身份验证失败,例如,请求包含无效的客户端 ID 或密码。在这种情况下,将发送 HTTP 401 响应。
    • invalid_grant – 授权代码(或密码授予类型的用户密码)无效或已过期。如果授权授予中指定的重定向 URL 与此访问令牌请求中指定的 URL 不匹配,这也是您将返回的错误。
    • invalid_scope – 对于包含范围(密码或 client_credentials 授予)的访问令牌请求,此错误表示请求中的范围值无效。
    • unauthorized_client – 该客户端无权使用所请求的授权类型。如果你例如限制哪些应用程序可以使用隐式身份验证,如果您为其他应用程序返回此错误。
    • unsupported_grant_type – 如果您请求授权服务器无法识别的授权类型,请使用此代码。请注意,未知的授权类型也使用此特定错误代码,而不是使用上面的 invalid_request 代码。

    返回带有两个可选参数的错误响应:error_descriptionerror_uri。这些旨在向开发人员提供有关错误的更多信息,而不是向最终用户展示提供信息。但是,请记住,无论您如何警告许多开发人员,许多开发人员都会将此错误文本直接传递给最终用户,因此最好确保它至少对最终用户也有一定帮助。

    参数error_description 只能是 ASCII 字符,最多只能是一到两句话描述错误情况。这个 error_uri 是链接到 API 文档的好地方,以获取有关如何修复遇到的特定错误的信息。

    整个错误响应以 JSON 字符串形式返回,与成功响应类似。以下是错误响应的示例。

    HTTP/1.1 400 Bad Request
    Content-Type: application/json
    Cache-Control: no-store
    
    {
      "error": "invalid_request",
      "error_description": "Request was missing the 'redirect_uri' parameter.",
      "error_uri": "See the full API docs at https://authorization-server.com/docs/access_token"
    }
  • 版权声明

    本文仅代表作者观点,不代表Code前端网立场。
    本文系作者Code前端网发表,如需转载,请注明页面地址。

    发表评论:

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    热门