2013-07-27 13 views
7

月前私は、oauth2を使ってgoogleで認証されたレールアプリを作成しました。特に、omniauth-google-oauth2 gemです。私は、認証を作成し、リフレッシュ・トークンを格納するためのすべての手順を実行しましたが、最近oauth2はレスポンスの一部として 'refresh_token'を戻しませんでした。omniauth google oauth2を使ってレールアプリの「refresh_token」を返すにはどうすればよいですか?

credentials: { 
    refresh_token: XXX, 
    token: YYY, 
    expires_at: 1374840767, 
    expires: true 
}, 

を今私は時間以内に期限が切れたトークン取り戻す:

credentials: { 
    token: YYY, 
    expires_at: 1374840767, 
    expires: true 
}, 

を私は本当に私がアプリケーション側で何をしたか分からないもともと私が含まれている応答を受信しましたこれを変更して、Googleで何かが変わったのかどうか、あるいはそれが何かだったのかどうかはわかりません。コンテキストのために、私のコードは次のようになります。

初期化子/ omniauth.rb:

Rails.application.config.middleware.use OmniAuth::Builder do 
    provider :google_oauth2, 'KEY', 'SECRET', {:scope => "userinfo.email,userinfo.profile,analytics.readonly,adsense.readonly"} 
end 

を、私は、応答を受け取るところauthentications_controller.rbは次のとおりです。

def create 
    auth = request.env["omniauth.auth"] 
    params = request.env["omniauth.params"] 
    project = Project.find(params['project_id']) 

    Authentication.create(:project_id => project.id, :provider => auth['provider'], :uid => auth['uid'], :access_token => auth['credentials']['refresh_token']) 
    flash[:notice] = "Authentication successful." 
    redirect_to owner_view_project_path(project) 
end 

は、それは何かが中に欠けていることは可能です私のinitializers/omniauth.rbファイル?私はオプションのハッシュに以下を追加しようとしたが、それはリフレッシュトークンを戻すようには見えなかった。

:approval_prompt => "force", :access_type => "offline" 

任意の助けをいただければ幸いです!前もって感謝します!

+0

この問題を解決しましたか?私は今、同じ問題に直面しています。私はあなたが解決策を見たいと思っています。ありがとう! –

答えて

8

プロンプト: '同意'はあなたにリフレッシュトークンを取得しています。このような何か作業をする必要があります:

Rails.application.config.middleware.use OmniAuth::Builder do 
    scopes = [ 
     # we need the profile scope in order to login 
     "https://www.googleapis.com/auth/userinfo.profile", 
     # this and other scopes could be added, but match them up with the 
     # features you requested in your API Console 
     "https://www.googleapis.com/auth/calendar" 
    ] 

    provider :google_oauth2, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, { scope: scopes.join(" "), access_type: 'offline', prompt: 'consent'} 
end 
+0

プロンプト: '同意'でした – okysabeni

+0

ありがとうプロンプト: '同意'が保存されました – chickensmitten

+0

背景:ユーザーが明示的にアクセスを確認したとき(常に最初のリクエストで発生する)、refresh_tokenのように見えます。承認のフォローアップ要求はGoogleが決定したため自動的に確認されますが、自動確認には「refresh_token」がありません(意味があります)。この回答は、 'refresh_token'が確実に存在するように強制的に同意する方法を示しています。これは、ユーザーが認証を確認するたびに照会することに注意してください。 – codener

2

私は見ての通り、あなたのプロバイダのスコープに

access_type: 'offline' 

を追加するのに十分です。

Googleの定義では、次のようなトリックが表示されます。アプリが初めてGoogleアカウントにアクセスできるようにするには、リフレッシュトークンにはが初めて提供されます。

Googleが送信した更新トークンをもう一度表示したい場合は、承認を拒否して認証を取り戻してください。

ここで元の定義をグーグル参照してください:これは最初のトークンリフレッシュを取得するアプリケーションになりますオフライン:。その後、ACCESS_TYPEを使用し、「アプリケーションは、ユーザーがブラウザに存在しない場合にアクセストークンを更新する必要がある場合アプリケーションがユーザーの認証コードを交換します。 (https://developers.google.com/identity/protocols/OAuth2WebServer

関連する問題