我必须承认我已经有很长一段时间没有这个问题,从来没有真正理解过.
说auth令牌就像一个保险箱的钥匙,当它到期时它不再可用了.现在我们给了一个魔术刷新令牌,可用于获取另一个可用的键,另一个......直到魔术键到期.那么为什么不将auth令牌的到期时间设置为与刷新令牌相同?为什么这么麻烦?
它的正当理由是什么,也许是历史原因?真的很想知道.谢谢
我有一个与YouTube直播API集成的程序.它运行在计时器上,因此我可以通过刷新令牌每隔50分钟编程一次获取新的访问令牌.我的问题是,为什么?
当我通过YouTube验证时,它给了我一个刷新令牌.然后,我使用此刷新令牌大约每小时获取一个新的访问令牌.如果我有刷新令牌,我总是可以使用它来获得一个新的访问令牌,因为它永远不会过期.所以我不知道这是多么安全,而不仅仅是从一开始就给我一个访问令牌,而不是整个刷新令牌系统.
I am referencing another SO post that discusses using refresh tokens with JWT.
JWT (JSON Web Token) automatic prolongation of expiration
I have an application with a very common architecture where my clients (web and mobile) talk to a REST API which then talks to a service layer and data layer.
I understand JWT token authentication, but I am a little confused at how I should use refresh tokens.
I want my JWT authentication to have the following properties:
JWT …
在Auth0中,您可以使用刷新令牌.在此链接中,我们可以看到许多返回的参数:
lock.showSignin({
authParams: {
scope: 'openid offline_access'
}
}, function (err, profile, id_token, access_token, state, refresh_token) {
// store refresh_token
});
Run Code Online (Sandbox Code Playgroud)
显然,access_tokens可用于检索用户配置文件数据.但这似乎是oauth特有的,我认为auth0使用openid?
id_token
和之间有什么区别access_token
?
我正在尝试设置一项网络服务来查询Google Play购买.我们会为客户存储订单信息,此服务会调用Google Play API来查询订阅详情.
每次我尝试查询购买时,它都会给我错误:
HTTP/1.1 400 Bad Request
{
"error":{
"errors":[
{
"domain":"global",
"reason":"invalid",
"message":"Invalid Value"
}
],
"code":400,
"message":"Invalid Value"
}
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试过的:
代码方面,我使用refresh_token来获取access_token:
String refreshToken = "1/ljll6d9ME3Uc13jMrBweqXugV4g4timYcXXXXXXXXX";
HttpPost request = new HttpPost("https://accounts.google.com/o/oauth2/token");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("client_id", client_id));
params.add(new BasicNameValuePair("client_secret", client_secret));
params.add(new BasicNameValuePair("refresh_token", refreshToken));
params.add(new BasicNameValuePair("grant_type", "refresh_token"));
request.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = httpClient.execute(request);
HttpEntity entity = response.getEntity();
String …
Run Code Online (Sandbox Code Playgroud) 我正在寻找一种以安全的方式验证我的移动应用程序用户的方法.移动应用程序是一个纯JS应用程序,并使用离子框架(和所以cordova).该应用程序只能通过REST API与我们的服务器通信.要求如下:
我发现了什么:
OAuth 2提供称为"刷新令牌"的长时间令牌.我想使用它的过期日期设置为一年.
然而,似乎没有强大的机制来保护这个标记.事实上,正如Jamsheed Kamarudeen对该答案的评论/sf/answers/504648441/所述,如果刷新令牌,客户端ID和秘密ID被盗(使用嗅探或直接从设备获取),攻击者将能够无限制地访问用户帐户......没有任何办法,AFAIK,知道它正在发生.
嗅探可能很困难,因为很明显,所有数据都将通过安全连接(SSL)发送,但从我的角度来看,它仍然可以进行管理.关于第二种攻击,"直接从设备中取出",我看到的每个解决方案都是关于在本地存储或浏览器cookie上存储数据(令牌或cookie)(例如,这篇文章在HTML5 Web App中使用OAuth2) .即使该帖子中的示例建议存储刷新令牌的哈希,我也看不出它的目的是什么,因为正如Mati Cicero的评论所提到的,它不会阻止攻击者能够检索到访问令牌,在我的情况下,可以无限制地访问用户的帐户.
此外,从我所看到的,本地存储和cookie太容易阅读.这还不够,还是我应该使用Android/iOS的原生安全存储?甚至本地本地存储似乎还不够(https://github.com/phonegap/phonegap/wiki/Platform-Security).
服务器端将由Spring实现.Spring-security提供的机制似乎比关于记忆我模式的OAuth 2更好(http://jaspan.com/improved_persistent_login_cookie_best_practice).但是,正如我所理解的那样,最终用户将无法在应用程序上登录两次(比方说,它的个人移动设备和专业移动设备).我承认这不是一个大问题,但它仍然不完美.最重要的是,最后,我们仍然存在有关cookie /令牌的存储安全问题.
这是我第一次寻找安全机制,所以也许我误解了一些机会主义,请让我知道.但是,我很惊讶地发现找到合适的流程有多困难.我确信这是所有移动应用程序的经典问题,但我找不到任何正确的方法来管理这个问题.
我的问题:正如您在上面所看到的,我没有找到一个安全的机制来在Web移动应用程序上设置"自动登录"过程.我该怎么设置?你有其他机械主义,而不是我发现的那些吗?
根据Google的文档,似乎只有脱机应用程序才需要刷新令牌(当用户不在时,可能会遇到过期访问令牌的应用程序).
访问令牌定期到期.如果您请求脱机访问与令牌关联的作用域,则可以刷新访问令牌而不提示用户获得权限(包括用户不存在时).
...
要求离线访问是任何需要在用户不在时访问Google API的应用程序的要求.例如,执行备份服务或在预定时间执行操作的应用程序需要能够在用户不在时刷新其访问令牌.默认访问方式称为在线.
但是,一般来说刷新令牌的描述以及特别是这个问题似乎都暗示,只要您想要请求新的访问令牌,就需要刷新令牌.
我想我会同意谷歌的解释,而不是使用刷新令牌.我对OIDC提供商的经验是,刷新的工作原理如下:
用户可能会看到一些重定向,但除了重新进行身份验证之外没有任何交互.鉴于此,如果用户总是出现在应用程序中,是否有必要使用刷新令牌?
刷新令牌的想法是,如果访问令牌被泄露,因为它是短暂的,攻击者有一个有限的窗口滥用它.
我明白了,但是如果攻击者访问刷新令牌,他们将能够获得一个新的身份验证令牌,我错了吗?这似乎只是推迟了长期存在的令牌安全漏洞......
关于这一点,你会在同一个答案中找到:
刷新令牌(如果受到攻击)是无用的,因为除了刷新令牌之外,攻击者还需要客户端ID和机密才能获得访问令牌.
那么使用刷新令牌和简单地辞职之间的区别是什么?如果您不希望用户再次重新输入,那么如何存储客户端ID和密码?
正如@FStephenQ指出的那样,刷新令牌只能使用一次:攻击者将能够获得一个新的身份验证令牌,但只能获得一次,而且只能获得一次.但是,一旦你使用了新的刷新令牌,你如何获得新的刷新令牌呢?如果你使用一个新的,那么攻击者也可以刷新他们的令牌......
实际问题是:如何让我的用户登录?在我使用的应用程序上,一旦我登录,我就不必再次登录了:他们是如何进行的?
我正在使用 JWT 对我的应用程序的用户进行身份验证。当用户登录时,他们会获得一个访问令牌和一个刷新令牌。为了保证刷新令牌的安全,我不会将其存储在客户端,而是将其与他们的帐户一起保存在后端,因此不容易访问。不过,我对刷新令牌的安全性感到困惑,这是我在阅读有关如何使用刷新令牌的在线资源时所理解的逻辑:
我担心的安全问题是,如果其他人(黑客)获得了访问令牌并使用它向 api 发送请求,如果令牌已过期,api 将使用刷新令牌来获得新的访问权限令牌 + 新的刷新令牌,并至少将访问令牌返回给黑客。
我读了这篇文章大约 5-6 次,我读了几遍这篇文章,以及一些关于这个主题的其他文章,他们都说了一些类似的话
确保安全地存储刷新令牌,因为它是长期存在的,access_token 是短暂的,所以没什么大不了的
但是根据我上面描述的流程,访问令牌是否是短暂的并不重要,刷新令牌将用于获取新的访问令牌并永久访问。
有什么我想念的吗?如果黑客持有过期的访问令牌,api 如何知道谁在发送请求?它仍然会使用刷新令牌发送一个新的。我应该以某种方式验证谁在发送请求吗?
更新
所以我明白,当请求新的访问令牌时,我需要发送刷新令牌、客户端 ID 和客户端机密。我遇到的问题是,像以前一样,黑客可以向我的 API 服务器发送请求,服务器从黑客那里获取被劫持的访问令牌,它会看到它已过期,因此它将发送刷新令牌,以及将 clientID/client 机密(存储为环境变量)发送到 Auth API 并取回新的访问令牌/刷新令牌,这使我们回到了同样的问题。
更新 2
关于这个主题的一些有趣的问题:
根据第二个问题和答案,似乎刷新令牌不是一种更安全的维护访问方式,只是更容易检测到黑客,因为不断请求身份验证/刷新令牌并使对方的令牌无效。问题是这只会在 2 个用户同时尝试访问资源时发生 - 如果只有黑客碰巧在给定时间段内处于活动状态,他将可以无限制地访问原始用户数据,直到原始用户尝试使用应用程序并访问受保护的资源
目前我正在尝试收集有关如何实现身份验证系统(登录)的知识。在我的研究期间,我尝试在我的后端实施基于 JWT 的解决方案。
我有一个快速服务器,它允许我注册一个用户,存储它的密码(加密)和它的电子邮件。
在登录之后,它会生成一个访问令牌(短期,5 分钟),以访问受保护的路由,以及一个刷新令牌(长期,7 天),以便在前一个过期后生成新的访问令牌。
在我当前的实现中,我将刷新令牌存储在我的数据库中,因此每次我想生成新的访问令牌时都可以使用它。
但这安全吗?据我了解,在我的数据库中存储访问令牌是危险的,因此最好创建一个短期存在的 cookie 存储。但是……刷新令牌?据我所知,这会很危险,因为它基本上允许生成新的访问令牌,所以我不明白为什么不简单地在我的数据库中存储一个长期存在的访问令牌,在每次登录时生成一个新的。
什么是刷新令牌呢?
由于我遵循了一些教程来实现这一点,这就是我的 refresh_token 路由的外观
//get a new access token with a refresh token
app.post('/refresh_token', (req, res) => {
const token = req.cookies.refreshtoken
//if no token in request
if(!token) return res.send({accesstoken : ''});
//if we have a token we verify it
let payload = null;
try{
payload = verify(token, process.env.REFRESH_TOKEN_SECRET);
}catch(err){
return res.send({accesstoken: ''});
}
//if token is valid check if user exist
const user = fakeDB.find(user => user.id === …
Run Code Online (Sandbox Code Playgroud) oauth-2.0 ×4
access-token ×3
jwt ×3
oauth ×3
security ×2
api ×1
auth-token ×1
auth0 ×1
cordova ×1
express-jwt ×1
google-play ×1
java ×1
javascript ×1
jwt-auth ×1
openid ×1
remember-me ×1
youtube-api ×1