如何使用 Google API 进行离线访问
Posted
技术标签:
【中文标题】如何使用 Google API 进行离线访问【英文标题】:How to get offline-access with Google APIs 【发布时间】:2017-09-19 15:39:15 【问题描述】:我正在尝试使用 Google API 获取 offline access
。我必须从 Google 日历中提取数据,而无需用户每次都登录。
我已将此添加到我的 Gemfile 中:
gem 'google-api-client', '~> 0.9'
...并将其添加到我的控制器中:
require 'google/api_client/client_secrets'
class Api::V1::CalendarAccountsController < Api::V1::BaseController
...
在我的行动中:
client_secrets = Google::APIClient::ClientSecrets.load(
File.join(
Rails.root,
'config',
'client_secrets.json')
)
@auth_client = client_secrets.to_authorization
@auth_client.update!(
:scope => 'https://www.googleapis.com/auth/calendar.readonly',
:redirect_uri => '/callback URL',
:additional_parameters =>
"access_type" => "offline",
"include_granted_scopes" => "true"
)
redirect_to @auth_client.authorization_uri.to_s
问题是 -- 即使我将 "access_type" 指定为 "offline",我仍然没有被问到获取 Google 权限列表中的离线访问权限(我在下面附上了屏幕截图)。
这是 Google 加载的页面(不能离线访问):
这是我调用@auth_client.authorization_uri.to_s
时生成的网址
https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=[ID]&redirect_uri=[callback]&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly&from_login=1&as=-23788065e9c098d9&pli=1&authuser=0
我错过了什么吗?
【问题讨论】:
【参考方案1】:你可以试试这样的:
client = Signet::OAuth2::Client.new(
client_id: your_client_id,
client_secret: your_secret_id,
authorization_uri: 'https://accounts.google.com/o/oauth2/auth',
scope: Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY,
redirect_uri: your_callback_url
)
client.update!(
additional_parameters:
access_type: 'offline',
prompt: 'consent'
)
redirect_to client.authorization_uri.to_s
请注意,我使用的是更新版本的 google-api-client
gem,配置方式如下:
gem 'google-api-client', '~> 0.11', require: 'google/apis/calendar_v3'
这样,Google 会要求您授予与日历 API 交互的权限,并正确设置 access_type
参数以授予您对相同 API 的离线访问权限。
这种方法会在您每次调用代码时提示用户授权。如果你想防止这种情况,你必须这样改变它:
client.update!(
additional_parameters:
access_type: 'offline'
)
如果您已经在没有access_type: 'offline'
参数的情况下授权了您的应用,Google 将在没有离线许可的情况下授予您一个身份验证令牌。要重置这种情况,只需进入your Google profile permissions 并撤销对您的应用程序的先前授权即可。然后再试一次。
(注意:signet
gem 是 googleauth
的依赖项,而 google-api-client
又是 google-api-client
的依赖项,因此您可以免费获得此代码,而无需向 Gemfile
添加更多 gem )
【讨论】:
【参考方案2】:尝试添加此代码。如果您的应用需要离线访问 Google API,请将 API 客户端的访问类型设置为 offline:
auth_client.update!(
:additional_parameters => "access_type" => "offline"
)
在用户授予对所请求范围的离线访问权限后,您可以在用户离线时继续使用 API 客户端代表用户访问 Google API。客户端对象将根据需要刷新访问令牌。
还可以使用 Google 客户端库,这将帮助您刷新访问令牌(离线访问)。
希望这会有所帮助。
【讨论】:
谢谢@Mr.Rebot -- 我已经添加了access_type
参数,但我仍然没有在谷歌的登录权限页面上得到离线访问提示(它只是要求read-only access to calendars
),我也没有在回复中得到refresh_token
。以上是关于如何使用 Google API 进行离线访问的主要内容,如果未能解决你的问题,请参考以下文章
Google 刷新访问令牌(离线访问)api 中的“unsupported_grant_type”