OAuth中的“离线”访问是什么意思?

67

关于OAuth服务器授予的离线访问,"offline"这个词究竟意味着什么?

它是否意味着,即使用户已从第三方应用或OAuth资源服务器(如Facebook、Google或Twitter)注销,资源服务器仍会返回有关用户的数据?


该术语在什么上下文中使用?因为我在OAuth RFCs中都找不到相关的参考。你能引用一句话吗? - thodic
https://developers.google.com/identity/protocols/OAuth2WebServer#offline - Water Cooler v2
https://developers.facebook.com/docs/roadmap/completed-changes/offline-access-removal - Water Cooler v2
2个回答

98

“离线访问”这个名字我认为非常不好,我想这只是谷歌使用的术语,据我所记,它并没有在OAuth的RFC中出现。

什么是谷歌的“离线访问”?

当您请求“离线访问”时,谷歌认证服务器会返回刷新令牌。刷新令牌使您的应用程序能够代表用户请求数据,即使用户不在您的应用程序前面也可以进行。

需要“离线访问”的应用程序示例

假设我有一个超级棒的应用程序,它可以下载您的Google Analytics数据,将其制作成漂亮的PDF文件,并每天早上通过电子邮件发送给您的统计数据。为了使此功能正常工作,我的应用程序需要在您不在场时访问您的Google Analytics数据,以获得权限。因此,超级棒的应用程序将请求“离线访问”,认证服务器将返回一个“刷新令牌”。借助该“刷新令牌”,超级棒的应用程序可以随时请求新的访问令牌并获取您的Google Analytics数据。

一个不需要离线访问的应用程序示例

让我们尝试Less Awesome应用程序,它允许您将文件上传到Google Drive。当您不在场时,Less Awesome应用程序不需要访问您的Google驱动器帐户。它只需要在您在线时访问它。因此理论上它不需要离线访问。但实际上它仍然获得了一个刷新令牌,这样它就不必再次请求您的权限(这就是我认为名称不正确的地方)。

来自OpenStack 文档 的有用引用:

如果授权代码交换中存在刷新令牌,则可以随时使用它来获取新的访问令牌。这被称为离线访问,因为用户在应用程序获取新的访问令牌时无需出现在浏览器中。


离线访问的真相

事实上,在很多情况下,认证服务器将无论如何都会向您返回刷新令牌: 您不必实际请求任何内容-它会自动给您。这使您能够在用户不在场时访问其数据。用户不知道您可以在没有他们的情况下访问他们的数据。只有JavaScript库和我认为PHP库才会隐藏刷新令牌,但它确实存在。

示例

只需发布(即HTTP POST请求):

https://accounts.google.com/o/oauth2/token?code={AuthCode}&
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&
redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code

这里是响应:
{
   "access_token": "ya29.1.AADtN_VSBMC2Ga2lhxsTKjVQ_ROco8VbD6h01aj4PcKHLm6qvHbNtn-_BIzXMw",
   "token_type":   "Bearer",
   "expires_in":   3600,
   "refresh_token": "1/J-3zPA8XR1o_cXebV9sDKn_f5MTqaFhKFxH-3PUPiJ4"
}

我现在可以离线访问这个用户的数据,而我从未告诉他们我会拥有这个权限。更多细节请参见这篇短文:Google 三脚架 OAuth2 流程


有用的阅读材料


1
属性/标志名称现在在你解释后有点意义了,但它仍然很令人困惑(听起来像与文件同步相关的内容)。 - Jaroslav Záruba
1
你提出了一些不正确的陈述。只有在形成授权提示时包含参数access_type=offline时,才会返回刷新令牌。为避免再次请求用户授权,不需要使用刷新令牌,因为如果他们之前已经授权访问,则每当您再次呈现它时,批准对话框将立即关闭。 - Eric Koleda
@EricKoleda 这个信息还有效吗?我在我的GET字符串中传递了access_type=offline给Google,但我仍然没有被要求获得离线访问权限。 - Qasim
1
尝试添加 prompt=consent。 - Linda Lawton - DaImTo
所有的名称都很差。授权服务器执行身份验证。 - Kermit
显示剩余4条评论

17

按照设计,OAuth流程返回的访问令牌会在一段时间后过期(Google访问令牌为1小时),作为一种安全机制。这意味着,任何想要使用用户数据的应用程序都需要用户最近进行过OAuth流程,也就是在线。请求离线访问将为应用程序提供一个刷新令牌,它可以用于生成新的访问令牌,使其能够在用户数据经过OAuth流程之后长时间访问用户数据,也就是当他们离线时。

当您的应用程序在用户不在场时继续运行时,需要获取离线访问权限。例如,如果有一些夜间批处理过程,或者如果您的应用程序响应外部事件,如推送通知。但是,如果您只在用户积极使用您的应用程序时访问用户数据,则无需获得离线访问权限。每次需要访问令牌时,只需将用户通过OAuth流程发送一次即可,如果他们以前授予了对您的应用程序的访问权限,则授权页面将立即关闭,使该过程对用户几乎不可见。

对于Google API,您可以在向用户呈现的授权URL中包括参数access_type=offline来请求离线访问权限。在使用已安装应用程序流程时,会自动请求离线访问权限和刷新令牌。


有什么看法,为什么谷歌总是返回一个刷新令牌,即使您的应用程序将来不需要访问它?您不必提供access_type = offline,您仍会获得刷新令牌,请检查我的链接,我已经测试过了。因此,如果我请求Google Analytics访问权限,则范围告诉用户我想要访问他们的数据,但它并没有告诉他们我也具有离线访问权限。 - Linda Lawton - DaImTo
只有在授权URL中access_type=offline时才会返回刷新令牌。你展示的URL是令牌URL,是应用程序在后台发出请求的地址。你可以在OAuth2 playground中测试离线和在线流程,使用齿轮图标更改访问类型、禁用强制批准提示等。 - Eric Koleda
请手动调用以下链接:http://www.daimto.com/google-3-legged-oauth2-flow/。我认为Oauth2 playground对其进行了一些微调。如果您直接使用本机客户端ID与身份验证服务器通信,则始终会获得刷新令牌。我尚未使用Web令牌测试过它,例如https://accounts.google.com/o/oauth2/token code=4/X9lG6uWd8-MMJPElWggHZRzyFKtp.QubAT_P-GEwePvB8fYmgkJzntDnaiAI&client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code。 - Linda Lawton - DaImTo
2
啊,似乎在使用安装的应用程序流程时自动提供了刷新令牌(请参见)。我已更新我的答案以刷新这个特殊情况。 - Eric Koleda
2
好的,那么为什么谷歌不告诉人们他们也在授予你的应用离线访问权限呢?我使用Eric的神奇应用程序,授权它访问我的谷歌驱动器,认证屏幕显示授予Eric的神奇应用程序访问您的驱动器,我授权了。现在,Eric的神奇应用程序可以随时阅读我所有的文件,而不仅仅是在运行神奇应用程序时。 - Linda Lawton - DaImTo
1
这个答案比被接受的那个更加真实。 - mr5

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