Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't Access Refresh Token / Can't Bypass Refresh Flow #454

Open
braintrustalex opened this issue Mar 22, 2024 · 1 comment
Open

Can't Access Refresh Token / Can't Bypass Refresh Flow #454

braintrustalex opened this issue Mar 22, 2024 · 1 comment

Comments

@braintrustalex
Copy link

TLDR: I've used the setup guide to get Google working as an SSO provider, up until my access_token expires. App throws A refresh_token is not available on subsequent POST to /auth/google_oauth2. Not using Devise. How can I mitigate this error, or bypass the refresh_token flow?

Setup

I've followed the setup guide in the README, and I am not using Devise.

I am able to POST /auth/google_oauth2 with a user and complete the account selection and consent screens, and am redirected to my callback endpoint with an access_token and refresh_token. However, once the access_token expires and my user is logged out of my application, when they POST /auth/google_oauth2 again to re-authenticate, I hit the token refresh flow within omniauth-oauth2: https://github.com/omniauth/omniauth-oauth2/blob/3a43234ab5dd36a75f9c125c58fcfe1a37b26805/lib/omniauth/strategies/oauth2.rb#L92

This fails every time with A refresh_token is not available https://gitlab.com/oauth-xx/oauth2/-/blob/main/lib/oauth2/access_token.rb?ref_type=heads#L118

This makes sense, since the refresh_token is supplied only on the first authorization call to Google. However, what I don't understand is how I'm supposed to handle this.

I can only make this work if I edit the gemfiles and add to the existing code:

# control how quickly my access_token expires for testing purposes
fresh[:expires_in] = 1
# the actual fix: manually forcing my refresh token into the gem flow
fresh[:refresh_token] = "my valid refresh_token"

Configuration

Gemfile:

# sso multiprovider
gem 'omniauth'
gem "omniauth-rails_csrf_protection"
gem 'omniauth-google-oauth2'

config/initializers/omniauth.rb:

Rails.application.config.middleware.use OmniAuth::Builder do
  if [feature flag enabled]
    provider :google_oauth2, 
      [google client id], 
      [google client secret], 
      scope: 'email',
      skip_jwt: true,
      access_type: 'online'
  end
end

OmniAuth.config.allowed_request_methods = %i[post]
OmniAuth.config.logger = Rails.logger

routes.rb

get '/auth/google_oauth2/callback', to: 'my_controller#google_callback'

index.html.erb:

= button_to 'Login with Google', '/auth/google_oauth2', method: :post

Questions

So to my questions:

  1. The guides mention to store the refresh_token, but not how or where. How am I supposed to store and pass the refresh_token to this gem?
  2. Can I bypass the refresh flow entirely? I'm only using this gem to authenticate users, and not to access any other Google API. Other issues on this gem suggest that only using prompt: 'consent' and access_type: 'offline' together are supposed to be the only way to get a refresh_token, but that doesn't influence whether this or underlying gems check for a refresh_token once the access_token is expired.
  3. Additionally, is there a way to pass an expires_at, or expire_in argument to the gem for shortening the access_token expiration time for testing purposes?

I've looked into this issue across the multiple omniauth gem dependencies, and this gem for 5+ days, and haven't gotten anywhere. Any feedback or answers would be deeply appreciated 🙏 ❤️

@zquestz
Copy link
Owner

zquestz commented May 6, 2024

if you are only using this for login, then there is no need to log them out when the access_token expires. The only time you need to worry about refreshing the token is if you actually need to use it...

Also what exactly are you posting to the /auth/google/oauth2 endpoint? It shouldn't be seeing any access token, and therefore it wouldn't be expired... unless you are passing in the expired token.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants