Devise with Omniauth for multiple models without STI

前端 未结 4 2002
情深已故
情深已故 2021-01-17 21:06

Is there any way to configure Devise Omniauth for multiple models without STI?

We have the models Students and Professors and we didn\'t want to use STI but now we r

4条回答
  •  清歌不尽
    2021-01-17 21:47

    Hi i came here with a similar problem and i came across with this solution, maybe i will help the next one. In my case i have two devise models where i work with omniauth in different ways, my first model was an user who can sign in with normal devise sign up or with omniauth, the second one was an artist, who just can sign up with regular sing up form, but i still going to need omniauth for authenticate a value from twitter, the verified field(That little check on twitters profiles that means if a famous user is really that guy).

    So when i came with i can't have two devise omniauthable models i just decide to use the same omniauth for both.

    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
      def all
        if artist_signed_in? and session["devise.authorize"] == current_artist.email
          session["devise.authorize"] = nil
          if current_artist.artist_profile.update_from_omniauth(request.env["omniauth.auth"])
            if current_artist.artist_profile.verified
              flash[:notice] = "You were verified"
            else
              flash[:alert] = "Twitter go well but you aren't verified there"
            end
            redirect_to edit_artist_profile_path(current_artist.artist_profile)
          else
            flash[:error] = "We can't connect with #{request.env["omniauth.auth"].provider.titleize.split(" ").first}"
            redirect_to edit_artist_profile_path(current_artist.artist_profile)
          end
        elsif !user_signed_in?
          user = User.from_omniauth(request.env["omniauth.auth"])
          if user.persisted?
            flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => user.provider.titleize.split(" ").first
            user.user_profile.from_omniauth(request.env["omniauth.auth"])
            sign_in_and_redirect user, :event => :authentication
          else
            session["count_errors"] = 0 if session["devise.user_attributes"] == nil
            session["devise.user_attributes"] = user.attributes
            redirect_to new_user_registration_url
          end
        else
          flash[:notice] = "You are already log in #{current_user.email}"
          redirect_to root_path
        end
      end
    
      def after_omniauth_failure_path_for(scope)
        if artist_signed_in? and session["devise.authorize"] == current_artist.email
          session["devise.authorize"] = nil
          edit_artist_profile_path(current_artist.artist_profile)
        else
          super
        end
      end
    
      alias_method :twitter, :all
    end
    

    For the first case, the normal users, we have

    elsif !user_signed_in?
    

    it will do the normal process and everything is just like every guide, but for the second case(the verified field and the artist profiles) i send a little session with some random value

    session["devise.authorize"]
    

    and i call the link with a new route from my artist profile controller

    <%= link_to "Verify with Twitter", artist_profiles_integrate_twitter_path %>
    

    who loads the session and redirects to the user omniauth route

    class ArtistProfilesController < ApplicationController
       ...
       def integrate_twitter
          session["devise.authorize"] = current_artist.email
          redirect_to user_omniauth_authorize_path(:twitter)
       end
     end
    

    Then i defined a couple of methods in each classes for working with omniauth, the first creates the user(based on railscast episode "devise-omniauth-revised") and the second just update the field on my artist profile model, you should override after_omniauth_failure_path_for(scope), this just returns the path for failures on login, using the same technique you change the after error path(when fails to connect with twitter, for example, it will redirect to user sign up path, and the session will be around for a while) we can have normal behavior and clean the session in all cases with this.

    Hope it helps, regards!

提交回复
热议问题