OAuth 2.0 在哪里安全地存储访问令牌以供长期使用
Posted
技术标签:
【中文标题】OAuth 2.0 在哪里安全地存储访问令牌以供长期使用【英文标题】:OAuth 2.0 where to securely store access token for long term use 【发布时间】:2018-07-21 23:43:36 【问题描述】:我正在使用使用 OAuth 2.0 的 API。它的流程是这样的:
-
在您的应用程序中,您有一个按钮,可将您重定向到授权服务器(在我的例子中是 API)。
您要么必须登录 API 网站并授予对您的应用程序的访问权限(按“允许”或“拒绝”按钮),或者如果您已经登录,只需授予对您的应用程序的访问权限(按“允许”或“拒绝”)。
您会被重定向回您的应用程序,并使用新的访问令牌进行 API 调用。
一切对我有用,一切都很好,但我不明白如何处理给定的访问令牌,以便已经授权访问您的应用程序的用户不必再次授予访问权限。等他几天后回来申请时。它会带来糟糕的用户体验(没有人愿意一次又一次地授予访问权限)。
注意:我正在使用Quizlet API
【问题讨论】:
【参考方案1】:首先,访问令牌应该是短暂的。认为它等于短暂的一次性凭证。如果您不确定,请查看此处链接的 Azure AD 令牌生命周期定义"Configurable token lifetime properties"。
建议使用定义短期访问令牌,例如 1 小时后过期。这样您就可以避免存储它们的复杂性。您只需将它们保存在内存中并使用它们来访问受保护的资源。
我不明白的是如何处理给定的访问令牌,以便已经授权访问您的应用程序的用户不必再次授予访问权限。等他几天后回到应用程序。
嗯,这里你应该说的是Refresh tokens。根据 OAuth 2.0 规范,其刷新令牌具有更长的生命周期。如果您查看我之前对 Azure 的引用,您会发现它们最多可以存活 90 天。对于 Google,刷新令牌会在 6 个月后过期(如果它们未被使用)。仍然可以撤销它们。
现在,当您使用刷新令牌时,您并没有使用它们来访问受保护的资源。应交换刷新令牌以获取访问令牌。因此,如果有人窃取它们,他们仍然需要客户端身份验证(例如:- 客户端 ID、重定向 uri 和客户端密码)来获取访问令牌。不过,保护他们是必须的。
无论如何,RFC6819 定义了一些您可以在5.3.3 部分中采用的可能性来存储秘密(令牌就是秘密)。您可以使用客户端存储机制或利用服务器支持来存储令牌。
如果您的应用程序有后端,一种可能性是将 cookie 与令牌相关联。 Cookie 值可以是您存储在后端(可能在数据库中)的令牌的哈希值。当后端收到具有有效 cookie 值的请求时,它可以检索针对它存储的令牌。这与“记住我”功能非常相似。
如果您无法控制令牌的生命周期(默认情况下它们是长期存在的)怎么办?
如果您可以轻松获得令牌,并且可以损害最终用户体验,请选择内存存储,您将始终检索新令牌以进行新访问。
如果您的应用程序有一个可以维护客户端之间状态的后端,请在后端推送和存储令牌。将客户端会话与令牌相关联,可能通过 cookie/会话。通过后端调用安全 API,无需将存储的令牌暴露给客户端应用程序。
【讨论】:
我明白了。现在,我没有收到刷新令牌,只有承载令牌,在“315360000”到期。默认的 url 参数“prompt_approval=force”/“prompt=consent”可以成为我没有收到它并且不断要求访问的原因吗?注意:我正在使用Quizlet API (php example) 好吧,315360000 的值并没有什么意义。可以配置令牌过期时间吗?我浏览了您指出的文档,是的,它没有提到刷新令牌。但是,你可以配置授权服务器吗? 我已经通读了整个 Quizlet 文档几次,但在任何地方都找不到任何关于使用 OAuth 配置任何内容的信息。事实上,他们声明他们提供的令牌持续 10 年:“Quizlet 访问令牌持续 10 年,有效地为第三方应用程序提供永久访问权限(无需用户重新授权)” @Tomeister 好的,我遇到了这个 - quizlet.com/api/2.0/docs/oauth2。好吧,尽管他们支持 Oauth 2.0,但似乎他们在草案阶段就采用了,没有考虑延长令牌寿命的影响。是的,这个数字是 10 年,这对于今天的标准来说太过分了。 总而言之,让用户在所有设备上只授权一次,我的选择是什么?只有 cookie?以上是关于OAuth 2.0 在哪里安全地存储访问令牌以供长期使用的主要内容,如果未能解决你的问题,请参考以下文章
如何安全地存储 Discord(OAuth2) 用户的访问令牌?