devise_token_auth
devise_token_auth copied to clipboard
Omniauth: One Time Code Flow
Summary: Does devise_token_auth support hybrid omniauth flow?
I'm trying to add Google Auth to an application that's using devise token auth. I'm using the omniauth-google-oauth2 gem for Google auth and the preferred flow that I'm using is the one time code flow
It seems that Devise Token Auth does not support this flow(Hybrid/One Time Code Flow) by default. Here is how I've gone about implementing the flow:
- My front end client makes a request to Google APIs and gets an Authorization Code
- I then make a POST request to
/api/v1/auth/google_oauth2/callback
providing the authorization code as a parameter. (This endpoint is processed byomniauth_callbacks#redirect_callbacks
)
When I make the above request, however, I get this error:
NoMethodError (undefined method `underscore' for nil:NilClass):
/Users/.../bundler/gems/devise_token_auth/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb:16:in `redirect_callbacks'
Close investigation reveals that request.env['omniauth.params'][
resource_class]` has not been set. I try to fix this my setting it in my overrides:
class OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController
before_action :set_omniauth_params, only: :redirect_callbacks
private
def set_omniauth_params
return if omniauth_params_present?
request.env['omniauth.params'] = {
'resource_class' => 'User',
'omniauth_window_type' => 'newWindow'
}
end
def omniauth_params_present?
request.env['omniauth.params']&.any?
end
end
This fixes my current issue, but then I keep running into various errors. In a bin to have a working solution, I made these few patches:
-
Pathed devise_token_auth (OmniauthCallbacksController) so as to know when One Time Code Flow is being used, and avoid a redirect when this flow is being used. Here's the diff
-
Added some overrides in the project:
class OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController
before_action :set_omniauth_params, only: :redirect_callbacks
private
def set_omniauth_params
return if omniauth_params_present?
omniauth_params = {
'resource_class' => 'User',
'omniauth_window_type' => 'newWindow'
}
request.env['omniauth.params'] = omniauth_params
end
def omniauth_params_present?
request.env['omniauth.params']&.any?
end
def assign_provider_attrs(user, auth_hash)
auth_hash = auth_hash.to_hash
super(user, auth_hash)
end
def get_resource_from_auth_hash
@resource = resource_class.find_by(email: auth_hash[:info][:email])
return super unless @resource
@resource
end
end
@morriskimani thanks for posting this, I had to do similar change to use Google Sign In in our react-native app.
Are there any plans to implement this pattern or make it smoother? @morriskimani I tried overriding the OmniauthCallbacksController
but I'm getting errors like this:
NoMethodError (undefined method `except' for nil:NilClass):
devise_token_auth (1.1.3) app/controllers/devise_token_auth/omniauth_callbacks_controller.rb:23:in `redirect_callbacks'
I'd love any help in trying to get this working and have spent a day working on this with no real progress.
Any updates on this? I'm currently also trying to implement One Time Code Flow with devise token auth. @jacferreira mind posting the code you wrote to get this working?
I tried for two days to implement this One Time Code Flow with rails 6, omniauth-google-oauth2 and devise-token-auth. Finally gave up on devise-token-auth library...
I just bumped on this thread now and decided to post something to support the request for a fix