1

我在为谷歌任务验证用户身份时遇到问题。

首先,它对用户进行身份验证并完美地做事。但是在第二次旅行中它会引发错误。

Signet::AuthorizationError - Authorization failed.  Server message:
{
  "error" : "invalid_grant"
}:

以下是代码:

def api_client code=""
  @client ||= (begin
      client = Google::APIClient.new
      client.authorization.client_id = settings.credentials["client_id"]
      client.authorization.client_secret = settings.credentials["client_secret"]
      client.authorization.scope = settings.credentials["scope"]
      client.authorization.access_token = "" #settings.credentials["access_token"]
      client.authorization.redirect_uri = to('/callbackfunction')
      client.authorization.code = code
      client
    end)
end

get '/callbackfunction' do
  code = params[:code]
  c = api_client code
  c.authorization.fetch_access_token!
  result = c.execute("tasks.tasklists.list",{"UserId"=>"me"})
  unless result.response.status == 401
    p "#{JSON.parse(result.body)}"
  else
    redirect ("/oauth2authorize")
  end
end

get '/oauth2authorize' do
  redirect api_client.authorization.authorization_uri.to_s, 303
end

执行第二个请求有什么问题?

更新:这是用户同意的链接和参数。

https://accounts.google.com/o/oauth2/auth?
access_type=offline&
approval_prompt=force&
client_id=somevalue&
redirect_uri=http://localhost:4567/oauth2callback&
response_type=code&
scope=https://www.googleapis.com/auth/tasks
4

2 回答 2

4

问题已解决。

解决方案:

回调函数中,通过用户同意提供的代码接收到的令牌存储在数据库中。

然后在其他函数中,只需从数据库中检索这些令牌并用于处理您想要针对 google 任务 API 的任何内容。

get '/callbackfunction' do
  code = params[:code]
  c = api_client code
  c.authorization.fetch_access_token!
  # store the tokens in the database.
end

get '/tasklists' do
  # Retrieve the codes from the database and create a client
  result = client.execute("tasks.tasklists.list",{"UserId"=>"me"})
  unless result.response.status == 401
    p "#{JSON.parse(result.body)}"
  else
    redirect "/oauth2authorize"
  end
end
于 2012-08-24T08:02:32.937 回答
0

我正在使用rails,并且我只将令牌存储在数据库中。然后使用脚本我在调用执行之前设置新客户端,以下是代码。

client = Google::APIClient.new(:application_name => 'my-app', :application_version => '1.0')
client.authorization.scope = 'https://www.googleapis.com/auth/analytics.readonly'
client.authorization.client_id = Settings.ga.app_key
client.authorization.client_secret = Settings.ga.app_secret
client.authorization.access_token = auth.token
client.authorization.refresh_token = true
client.authorization.update_token!({access_token: auth.token})

client.authorization.fetch_access_token!

if client.authorization.refresh_token && client.authorization.expired?
    client.authorization.fetch_access_token!
end

puts "Getting accounts list..."

result = client.execute(:api_method => analytics.management.accounts.list)
puts " ===========> #{result.inspect}"
items = JSON.parse(result.response.body)['items']

但是,它给出了你面临的同样的错误,

    /signet-0.4.5/lib/signet/oauth_2/client.rb:875:in `fetch_access_token': Authorization  failed.  Server message: (Signet::AuthorizationError)
{
  "error" : "invalid_grant"
}
    from /signet-0.4.5/lib/signet/oauth_2/client.rb:888:in `fetch_access_token!'

请提出为什么它不能使用给定的令牌?我用过oauth2,所以用户已经被授权了。现在我想访问 api 并获取数据...

===================更新===================

好的,有两个问题,

  1. 权限要添加到devise.rb,

    config.omniauth :google_oauth2, Settings.ga.app_key,Settings.ga.app_secret,{ 
      access_type: "offline", 
      approval_prompt: "" ,
      :scope => "userinfo.email, userinfo.profile, plus.me, analytics.readonly"
    

    }

  2. refresh_token 必须传递给 API 调用,否则无法授权。

我希望这对面临类似问题的人有所帮助。

于 2013-07-31T12:56:22.053 回答