Months ago I created a rails app that authenticated with google using oauth2 - specifically, the omniauth-google-oauth2 gem. I had all the steps working to create the authentication and store a refresh token, but recently oauth2 stopped sending back a 'refresh_token' as part of the response. Originally I was receiving a response that contained:
credentials: {
refresh_token: XXX,
token: YYY,
expires_at: 1374840767,
expires: true
},
Now I only get back the token that expires within an hour:
credentials: {
token: YYY,
expires_at: 1374840767,
expires: true
},
I really don't know what I did on the application side to change this, so I'm not sure if something changed with google, or if it was something I did. For context, my code looks like:
initializers/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 is where I receive the response:
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
Is it possible something is missing in my initializers/omniauth.rb file? I've tried adding the following to the options hash, but that didn't seem to bring back the refresh token:
:approval_prompt => "force", :access_type => "offline"
Any help would be greatly appreciated! Thanks in advance!
To revoke tokens by user ID, you must first configure the OAuth 2.0 policy to add the user ID to the access token. By including end user IDs in access tokens, you will then be able to revoke tokens by end user ID.
The prompt: 'consent' is getting you a refresh token. Something like this should work:
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
As I see, it is enough to add
access_type: 'offline'
to your provider's scope.
The trick is as follows in the Google definition: the refresh token is supplied only in the first time that your app get access to the google account.
Deny authorization and regain authorization if you want to see, again, the refresh token beeing sent by google.
See google original definition here: "If your application needs to refresh access tokens when the user is not present at the browser, then use access_type: offline. This will result in your application obtaining a refresh token the first time your application exchanges an authorization code for a user." (https://developers.google.com/identity/protocols/OAuth2WebServer)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With