OAuth2.0中刷新令牌的用途

3
我正在实现一个OAuth2.0服务器,并尝试阅读刷新令牌的概念,以及如何使用它来调用访问令牌,以及如何安全地存储它。有一件事让我感到困惑,那就是"由于Auth2.0令牌是短期令牌,假设在成功登录后服务器给我一个像这样的令牌:"
{
    "token_type":"bearer",
    "access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiVlx1MDAxNcKbwoNUwoonbFPCu8KhwrYiLCJpYXQiOjE0NDQyNjI1NDMsImV4cCI6MTQ0NDI2MjU2M30.MldruS1PvZaRZIJR4legQaauQ3_DYKxxP2rFnD37Ip4",
    "expires_in":3600,
    "refresh_token":"fdb8fdbecf1d03ce5e6125c067733c0d51de209c"
}

由于访问令牌是短期令牌,在我的情况下将在1小时后过期。

假设用户正在使用其访问令牌凭据浏览受保护的资源,在一段时间后,其访问令牌已过期,他的请求会返回以下响应:

{
  "code":401,
  "error":"invalid_token",
  "error_description":"The access token provided has expired."
}

现在可以使用存储在浏览器cookie中的新刷新令牌生成新令牌,但是每当访问令牌在一个小时内过期时,客户端的有效请求会由于过期的访问令牌而被拒绝,这样用户体验不会受到影响吗?我们必须先获取新的访问令牌,然后再尝试该请求。

获取刷新令牌是否只能像这样工作,或者我错过了一些重要的概念?

此外,如何安全地将刷新令牌存储在cookie中,因为这也不是最好的安全存储方式?


2
这就是为什么大多数开发人员会在访问令牌过期前5分钟检查expires_in并获取新的访问令牌。这样用户就不会受到影响。通常,当我获得访问令牌时,我会将当前时间增加3600,然后存储该值,这样我就知道何时需要获取新的访问令牌。 - Linda Lawton - DaImTo
@DaImTo,我该如何在浏览器上安全地存储“刷新令牌”? - Robins Gupta
只需将其转储到 cookie 或会话值中,对于没有创建它的客户端 ID 和客户端密钥的任何人来说都是无用的,我会假设该代码保留在服务器端。 - Linda Lawton - DaImTo
2个回答

2

刷新令牌是一种特殊的令牌,可以随时用于获取更新后的id_token。应用程序必须安全地存储刷新令牌,因为它们实际上允许用户永久保持身份验证。

OAuth的认证请求响应可能会发出一个id_token。此令牌可用于对受保护的API进行身份验证调用。

除了签名等其他安全措施外,OAuth具有由exp声明指示的过期日期。但是,在设备(例如桌面或智能手机)上本地安装的应用程序可能希望避免每次令牌过期时要求用户输入凭据。

刷新令牌允许应用程序直接请求OAuth发出新的id_token,而无需重新进行身份验证。只要刷新令牌没有被撤销,这就起作用。

安全注意事项

由于刷新令牌永不过期,因此重要的是提供一种撤销刷新令牌的方法。这可以通过仪表板手动完成,也可以通过Auth的API进行程序化处理。

可以为每个应用程序、用户和设备组合发放和撤销刷新令牌。要撤销刷新令牌,可以调用撤销刷新令牌端点:

DELETE https://YOUR_NAMESPACE/api/users/<user id>/refresh_tokens/<refresh token>

{
  "Authorization":   "Bearer <your access token>",
}

获得刷新令牌

要获得刷新令牌,必须在通过/authorize端点启动身份验证请求时包含offline_access范围和任意设备名称。例如:

GET https://YOUR_NAMESPACE/authorize/?
    response_type=token
    &client_id=YOUR_CLIENT_ID
    &redirect_uri=YOUR_CALLBACK_URL
    &state=VALUE_THAT_SURVIVES_REDIRECTS
    &scope=openid%20offline_access
    &device=my-device

使用刷新令牌

要获取新的id_token,需要使用委派终端点:

POST https://YOUR_NAMESPACE/delegation
Content-Type: 'application/json'
{
  "client_id":       "YOUR_CLIENT_ID",
  "grant_type":      "urn:ietf:params:oauth:grant-type:jwt-bearer",
  "refresh_token":   "your_refresh_token",
  "api_type":        "app"
}

这个请求的响应可能如下所示:

{
  "token_type": "Bearer",
  "expires_in": 30000,
  "id_token": "eyJ..."
}

expires_in参数表示新JWT的生命周期,以秒为单位。它可以通过JWT的exp和iat声明之间的差异来计算。 重要建议:仅在id_token过期时使用refresh_token获取新令牌。例如,每次调用API时都调用端点以获取新令牌是一种不好的做法。在Auth0中有速率限制,将限制可以使用相同令牌从某个IP到此端点的请求量。 如需进一步阅读,请尝试下面的链接 https://auth0.com/docs/refresh-token

1
刷新令牌是一种用于获取另一个有效令牌以与使用的API进行交互的令牌,因为令牌的生命周期很短。由于令牌的生命周期很短,每次想要访问API时都必须从用户那里获取另一个oauth2.0凭据。如何避免这种情况?-> 使用刷新令牌。
正如所说,刷新令牌根本不是用于API访问的令牌,它只是一种用于每次获取新的短期令牌的令牌。
然后,您的第一个登录凭据会获得用户同意的令牌和刷新令牌,然后您不再需要用户同意,只需使用刷新令牌即可。
不确定我是否回答了您的问题 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接