我对oauth2中的刷新令牌有点困惑。如它所说的访问令牌限制了黑客可以使用用户凭证的1小时的时间窗口,刷新令牌是万岁令牌,可以用来重新创建访问令牌。
我很困惑,如果有人从cookie中窃取了访问令牌,他也可以窃取刷新令牌,并可以使用刷新令牌创建新的访问令牌,因为我在JQuery中有ajax请求(客户端)
jQuery(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {
//console.log('event');console.log(event);
//console.log('jqXHR');console.log(jqXHR);
//console.log('ajaxSettings');console.log(ajaxSettings);
//console.log('thrownError');console.log(thrownError);
if(jqXHR.status == 403)
{
console.log('User is not Loged in Redictet to Login Page');
}
if(jqXHR.status == 401)
{
var refresh_token = Cookies.get('refresh_token');
if(refresh_token != undefined)
{
$.ajax({
url: CONNECT_API_URL+'/refresh-token',
type: "POST",
data:{ refresh_token: refresh_token },
success: function(response, status, jqXHR){
if(response.access_token != undefined)
{
var expires_in = new Date(new Date().getTime() + response.expires_in * 1000);
var access_token = response.token_type+' '+response.access_token;
Cookies.set('access_token', access_token, { expires: expires_in });
Cookies.set('refresh_token', response.refresh_token, { expires: 14 });
$.ajax(ajaxSettings); // Re send same ajax request with access token in cookie has been set
}
else
{
console.log('Redirect to login page.');
}
},
});
}
}
});
在这篇题为刷新令牌:何时使用它们以及它们如何与JWTs交互的博客文章中,您的问题中的主题得到了很好的讨论。
那篇文章的引文:
刷新令牌通常受到严格的存储要求的约束,以确保它们不被泄露。
5.2.2.1.刷新令牌的限制发行
授权服务器可以基于适当的策略决定不发出刷新令牌。由于刷新令牌是长期凭据,它们可能会遭到盗窃。例如,如果授权服务器不信任客户端安全地存储此类令牌,则它可能拒绝向此类客户端颁发刷新令牌。
这意味着您可能应该仔细考虑要存储刷新令牌的位置。这篇文章在哪里存储您的JWTS-Cookies vs HTML5 Web存储正是关于这个主题的。
授权服务器应该将每个刷新令牌与发出该令牌的客户端的标识符匹配。授权服务器应该检查每个刷新访问令牌的请求是否存在相同的“client_id”。如果可能(例如,机密客户机),授权服务器应该对相应的客户机进行身份验证。
这是针对刷新令牌盗窃或泄漏的对策。
刷新令牌只能使用一次。当使用refresh_token
时,它将返回一个新的access_token
和一个新的refresh_token
。它使旧的refresh_token
无用,这意味着它不能再使用了。
刷新令牌旋转旨在自动检测并防止来自不同应用程序/设备的并行使用相同刷新令牌的尝试。如果令牌从客户端被盗并随后被攻击者和合法客户端使用,就会发生这种情况。其基本思想是在每次刷新请求时更改刷新令牌值,以便检测使用旧刷新令牌获取访问令牌的尝试。由于授权服务器无法确定是攻击者还是合法客户端试图访问,因此,在这种访问尝试的情况下,有效的刷新令牌和与其相关联的访问授权都将被吊销。
OAuth规范支持这种度量,因为令牌的响应允许授权服务器返回一个新的刷新令牌,即使对于授权类型为“refresh_token”的请求也是如此。
注意:由于必须确保使用当前有效的刷新令牌,因此此措施可能会在群集环境中导致问题。在这种环境下,其他措施可能更合适。
您的访问和刷新令牌可能会在客户机上遭到破坏,但令牌也可能会在客户机和服务器之间的某个地方被截获。refresh_token
只向客户机发送一次,而access_token
在每个请求中都被发送到服务器,这就是为什么中间人得到您的access_token
的机会要比您的refresh_token
受到损害的机会大得多。
一般来说,充分理解OAuth2协议是很好的,这样您就可以正确地实现它。关于安全,我想简单地说:
我希望这能让你对这个话题有所了解。如果有人想添加或更正我的帖子,请随时编辑/更新/赞美答案或留下评论。
请求你分享你的想法。 提前道谢。
我以前在一个OAuth2应用程序中工作过,其中的逻辑是在旧的访问令牌过期后通过刷新令牌生成新的访问令牌。 如果访问令牌在30分钟后过期,然后您只需要传入刷新令牌(但没有重新生成),那么刷新令牌的意义是什么?
我正在实现一个支持刷新令牌的OAuth2服务器,但是,有一些东西我不能完全理解。 当用户通过请求新的访问令牌,并且他/她请求的范围小于原始访问令牌的范围(5个范围中的3个)时。刷新令牌应该具有原始作用域还是刷新令牌应该具有请求的新作用域? > 如果刷新令牌请求了新的作用域,这是否意味着如果它们继续请求较小的作用域,它们最终将耗尽作用域? 刷新令牌是否应保留原始作用域?这意味着返回的访问令牌对于刷新
我理解客户机应用程序使用refresh_token(连同它的凭据)为最终用户(资源所有者)获取新的访问令牌,而不是存储最终用户的用户名/密码,并在每次access_token过期时发送它们。 然而,在我看来,这听起来像refresh_token和access_token一样好,它几乎只是一个额外的服务器调用,所以为什么不直接使用它,即如果refresh token是有效的授予访问权限呢?
application.yml:
下面的代码使用Google oauth2机制登录用户。我们需要在用户离线时处理用户日历的更新,所以我们最终需要“刷新令牌”。grantOfflineAccess()的结果是否返回刷新令牌(在下面,我可以看到response.code包含一个可能是刷新令牌的值)? 我如何获得一个刷新令牌,可以用来(服务器端)创建新的访问键,以便离线访问用户的谷歌日历?