2012-08-23 40 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調用,否則它無法授權。

我希望這有助於某人,面臨類似的問題。