简体   繁体   中英

Rails - Google oauth2 request.env['omniauth.auth'] is nil using omniauth with multiple models

I am working on a rails app and setting up Google OAuth2 using the omniauth google oauth2 gem . There are 2 models that are using devise and omniauth, and following this guide for using devise with multiple models (From the devise team) does not work.

Currently, there is 1 existing model using devise which is using an omniauth strategy for facebook. The set up for that model looks like this

devise :invitable, :database_authenticatable, :registerable,
         :trackable, :validatable, :omniauthable, omniauth_providers: [:facebook, :facebook_access_token]

On a seperate model, I want to add an omniauth strategy for google (that model is also using devise ) which has the standard devise set up

devise :database_authenticatable,
         :recoverable, :rememberable, :trackable, :validatable

currently in devise.rb there is set up for facebook omniauth

config.omniauth :facebook, ENV['facebook_app_id'], ENV['facebook_app_secret'], { scope: 'comma,seperated,fields', info_fields: 'comma,seperated,fields' }

and in omniauth.rb there is set up for google

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], 
  {
    scope: 'userinfo.email, userinfo.profile',
    prompt: 'select_account',
    image_aspect_ratio: 'square',
    image_size: 50
  }
end

in routes.rb there are various routes for devise/omniauth

devise_for :users, path: 'users', controllers: {omniauth_callbacks: "users/omniauth_callbacks"} do
    get 'sign_out', to: 'devise/sessions#destroy', as: :destroy_user_session
  end

devise_for :admin_users, path: 'admin/admin_users'

Note - there is no controllers: {omniauth_callbacks: "admin/omniauth_callbacks"} for admin_users in routes.rb because I get this error booting up my server

Please add `devise :omniauthable` to the `AdminUser` model

and if omniauthable is added to both models, I get this error when running my local server

Wrong OmniAuth configuration. If you are getting this exception, it means that either:
1) You are manually setting OmniAuth.config.path_prefix and it doesn't match the Devise one
2) You are setting :omniauthable in more than one model
3) You changed your Devise routes/OmniAuth setting and haven't restarted your server

The current set up in the initialization files and routes.rb is allowing the server to turn on. Because I cannot use this the way the guide has shown, I am using the 1-time hybrid auth flow outlined in the omniauth-google-oauth2 gem guide. In the page rendering that view, I have the javascript set up like this

<script src="https://apis.google.com/js/platform.js?onload=init"></script>
<script type="text/javascript">
function init() {
  gapi.load('auth2', function() {
    // Ready.
    $('.google-login-button').click(function(e) {
      e.preventDefault();
      gapi.auth2.authorize({
        client_id: "SOMEKEY.apps.googleusercontent.com",
        cookie_policy: 'single_host_origin',
        scope: 'email profile',
        response_type: 'code'
      }, function(response) {
        if (response && !response.error) {
          // google authentication succeed, now post data to server.
          jQuery.ajax({type: 'POST', url: '/admin/admin-signin', data: response,
            success: function(data) {
              // response from server
              console.log('********************')
              console.log(data)
              console.log('********************')
            }
          });        
        } else {
          // google authentication failed
          console.log('********************')
          console.log(response)
          console.log('********************')
        }
      });
    });
  });
};
init();
</script>

<div class="authform">
  <a class="google-login-button">Sign in</a>
</div>

and I have added that route like this

namespace :admin do 
  ...
  post '/admin-signin', to: 'application#google_oauth2'
end

Currently, this set up lets me render the form prompt from google, I can select my account to use. Once I select the account to use, I can see the params being sent to the controller action and it looks like this

{"code"=>"4/LONGCODEOFSTRINGSANDNUMBERS", 
 "scope"=>"email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid", 
"authuser"=>"1", "hd"=>"COMPANY", "session_state"=>"b0c030e5f1304f58695e19aa29cb73c942ac69b6..163d", 
"prompt"=>"consent", "controller"=>"admin/application", "action"=>"google_oauth2"}

My controller action to handle this call looks like this

def google_oauth2
  @admin_user = AdminUser.from_omniauth(request.env['omniauth.auth'])

  if @admin_user.persisted?
    flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google'
    sign_in_and_redirect @admin_user, event: :authentication
  else
    session['devise.google_data'] = request.env['omniauth.auth'].except(:extra) 
    redirect_to :back, alert: @admin_user.errors.full_messages.join("\n")
  end
end

But the problem is request.env['omniauth.auth'] is nil and no data is being sent with it. It looks like i might have a couple options

  • is there something additional I need to do on my end to get request.env['omniauth.auth'] to be present? Is there a callback I send somewhere else to google to get the request.env['omniauth.auth'] data back?
  • Implement an omniauthable model that both users and admin_users can use

Does anyone see what I'm doing wrong, or what can be added to this? All I want from the google oauth is this auth hash that should be present in request.env['omniauth.auth'] .

Thanks for the help

This was a very specialized and isolated issue that might not be too much help to someone else running across this. I made this app inside of an organization that had various google keys. So the solution for this problem for me was to use the proper keys. The keys I used before did not satisfy the settings of the organization and it was not working as a result. Once I used the proper keys for that organization, this was able to work just fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM