【发布时间】:2014-01-04 13:56:31
【问题描述】:
我希望有更多经验的人可以帮助我了解这个 Google API。
我只是基于 ruby 快速入门示例应用构建了一个演示应用,以探索这个 API。我有一个 Rails 4.0 应用程序并已成功(大部分)安装了 Google+ 登录。
一旦用户的访问令牌过期,一切都会出错。
我的测试应用的成功之处:
- 让用户登录并检索客户端的访问令牌以及服务器代码。
- 用服务器代码交换访问令牌和刷新令牌和 id 令牌
- 创建包含访问令牌和刷新令牌的令牌对对象,然后将其存储在会话哈希中
- 然后我的应用可以请求获取用户人员列表、插入时刻等。
所以我的问题是,使用刷新令牌获取新访问令牌的正确方法是什么?
使用下面的代码,访问令牌过期后我收到“无效凭据”的错误
如果我打电话给$client.authorization.refresh!,我会收到“无效请求”的错误
config/initializers/gplus.rb
# Build the global client
$credentials = Google::APIClient::ClientSecrets.load
$authorization = Signet::OAuth2::Client.new(
:authorization_uri => $credentials.authorization_uri,
:token_credential_uri => $credentials.token_credential_uri,
:client_id => $credentials.client_id,
:client_secret => $credentials.client_secret,
:redirect_uri => $credentials.redirect_uris.first,
:scope => 'https://www.googleapis.com/auth/plus.login',
:request_visible_actions => 'http://schemas.google.com/AddActivity',
:accesstype => 'offline')
$client = Google::APIClient.new(application_name: " App", application_version: "0.1")
*app/controllers/google_plus_controller.rb*
class GooglePlusController < ApplicationController
respond_to :json, :js
def callback
if !session[:token]
# Make sure that the state we set on the client matches the state sent
# in the request to protect against request forgery.
logger.info("user has no token")
if session[:_csrf_token] == params[:state]
# Upgrade the code into a token object.
$authorization.code = request.body.read
# exchange the one time code for an access_token, id_token and refresh_token from Google API server
$authorization.fetch_access_token!
# update the global server client with the new tokens
$client.authorization = $authorization
# Verify the issued token matches the user and client.
oauth2 = $client.discovered_api('oauth2','v2')
tokeninfo = JSON.parse($client.execute(oauth2.tokeninfo,
:access_token => $client.authorization.access_token,
:id_token => $client.authorization.id_token).response.body)
# skipped
token_pair = TokenPair.new
token_pair.update_token!($client.authorization)
session[:token] = token_pair
else
respond_with do |format|
format.json { render json: {errors: ['The client state does not match the server state.']}, status: 401}
end
end # if session csrf token matches params token
# render nothing: true, status: 200
else
logger.info("user HAS token")
end # if no session token
render nothing: true, status: 200
end #connect
def people
# Check for stored credentials in the current user's session.
if !session[:token]
respond_with do |format|
format.json { render json: {errors: ["User is not connected"]}, status: 401}
end
end
# Authorize the client and construct a Google+ service
$client.authorization.update_token!(session[:token].to_hash)
plus = $client.discovered_api('plus', 'v1')
# Get the list of people as JSON and return it.
response = $client.execute!(api_method: plus.people.list, parameters: {
:collection => 'visible',
:userId => 'me'}).body
render json: response
end
#skipped
end
任何帮助表示赞赏。额外的问题,我用作指南的示例应用程序构建了一个全局授权对象(Signet::OAuth2::Client.new) - 但是我在过去一天阅读的其他文档已经声明为每个 API 请求构建一个授权对象。哪个是正确的?
【问题讨论】:
-
能否提供 HTTP 层跟踪?请匿名 client_secret 和 user_ID。
标签: ruby-on-rails ruby google-plus google-oauth google-api-client