2012-08-23 60 views
1

我有问题来验证谷歌任务的用户。谷歌任务API认证问题ruby

起初它认证用户并做完美的事情。但是在第二次旅行中会引发错误。

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 
+0

我只是随机地产生了这个异常 - 不得不启动脚本五次,直到它工作。 – Nakilon

回答

3

问题已修复。

解决方案:

callbackFunction参数它们通过由用户同意提供的代码接收到的令牌被存储在数据库中。

然后在其他函数中,只需从数据库中检索这些标记,然后使用它来处理任何您想要的对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 
0

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

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并获取数据...

=================== UPDATE ========== =========

好了,两个问题都在那里,

  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调用,否则它无法授权。

我希望这有助于某人,面临类似的问题。