devise_token_auth icon indicating copy to clipboard operation
devise_token_auth copied to clipboard

Omniauth: One Time Code Flow

Open morriskimani opened this issue 6 years ago • 4 comments

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 by omniauth_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:

  1. 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

  2. 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 avatar Jul 12 '18 17:07 morriskimani

@morriskimani thanks for posting this, I had to do similar change to use Google Sign In in our react-native app.

jacferreira avatar Dec 26 '18 15:12 jacferreira

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.

lassiter avatar Jan 17 '20 02:01 lassiter

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?

macgill4444 avatar Mar 17 '20 22:03 macgill4444

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

KoderMAL avatar Nov 11 '20 18:11 KoderMAL