我正在实现一个OAuth2.0 服务器
并尝试阅读刷新 token 的概念
以及如何使用调用访问 token 以及如何安全地存储它。
其中一个听起来让我很困惑的是`因为 Auth2.0 token 是短暂的 token 并且假设在成功登录后服务器给了我一个像这样的 token :
{
"token_type":"bearer",
"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiVlx1MDAxNcKbwoNUwoonbFPCu8KhwrYiLCJpYXQiOjE0NDQyNjI1NDMsImV4cCI6MTQ0NDI2MjU2M30.MldruS1PvZaRZIJR4legQaauQ3_DYKxxP2rFnD37Ip4",
"expires_in":3600,
"refresh_token":"fdb8fdbecf1d03ce5e6125c067733c0d51de209c"
}
因为访问 token 是短期 token ,在我的例子中它将在 1 小时后过期。
假设用户正在使用其访问 token
凭据浏览 protected 资源
,一段时间后其访问 token 过期并且他的请求返回如下响应。
{
"code":401,
"error":"invalid_token",
"error_description":"The access token provided has expired."
}
现在可以使用存储在浏览器 cookie 中的新 刷新 token
生成新 token ,但用户体验不会受到影响,因为每次访问 token 都在一个小时后,由于访问 token 过期,客户端的有效请求被拒绝,然后我们必须首先获取新的访问 token ,然后再次尝试该请求。
Does fetching of refresh token works like that only or I am missing some important concept?
此外,如何在 cookie 中安全地存储刷新 token ,因为它也不是最安全的存储方式?
最佳答案
刷新 token 是一种特殊的 token ,可用于随时获取更新的 id_token。刷新 token 必须由应用程序安全存储,因为它们本质上允许用户永远保持身份验证。
身份验证请求的响应可能导致 OAuth 发出 id_token。此 token 可用于对安全 API 进行经过身份验证的调用。
在签名等其他安全措施中,OAuth 有一个由 exp 声明指示的到期日期。但是,本地安装在台式机或智能手机等设备上的应用程序可能希望避免在每次 token 过期时都要求用户输入凭据。
刷新 token 允许应用程序请求 OAuth 直接颁发新的 id_token,而无需重新验证。只要刷新 token 没有被撤销,这就有效。
安全注意事项
因为刷新 token 永不过期,所以提供一种撤销它们的方法很重要。这可以从仪表板手动完成,也可以通过 Auth 的 API 以编程方式完成。
可以为应用程序、用户和设备的每种组合颁发和撤销刷新 token 。要撤销刷新 token ,您可以调用撤销刷新 token 端点:
DELETE https://YOUR_NAMESPACE/api/users/<user id>/refresh_tokens/<refresh token>
{
"Authorization": "Bearer <your access token>",
}
获取刷新 token
要获取刷新 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
使用刷新 token
要获取新的 id_token,使用委托(delegate)端点:
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 获取新 token 。例如,每次执行 API 调用时调用端点以获取新 token 是一种不好的做法。 Auth0 中有速率限制,这将限制从特定 IP 到此端点使用相同 token 可以完成的请求数量。
要进一步阅读,请尝试以下链接
关于authentication - OAuth2.0中Refresh Token的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37270361/