Rails 4,Devise,Omniauth(有多个提供商)

我花了几天时间在设计和omniauth上观看RailsCasts,然后通过相关教程来设置使用这些gem的身份validation系统。 我认为RailsCasts已经过时了,试图修补其他教程的差距正在创造各种问题。

请任何人都可以建议我可以用作实施该系统的基础的当前教程。 我有单独的用户和身份validation模型(用户有许多身份validation)。

我真的很想在rails 4上使用devise和omniauth(使用CanCan for capabilities),但是在试图找到一个基本设置(使用psql作为数据库)时,我正在撕裂我的头发。

要将Devise与多个身份validation提供程序一起使用,您还需要1个模型 – 授权

#authorization.rb # == Schema Information # # Table name: authorizations # # id :integer not null, primary key # user_id :integer # provider :string(255) # uid :string(255) # token :string(255) # secret :string(255) # created_at :datetime # updated_at :datetime # profile_page :string(255) # class Authorization < ActiveRecord::Base belongs_to :user end 

用户模型的代码

 #user.rb SOCIALS = { facebook: 'Facebook', google_oauth2: 'Google', linkedin: 'Linkedin' } has_many :authorizations def self.from_omniauth(auth, current_user) authorization = Authorization.where(:provider => auth.provider, :uid => auth.uid.to_s, :token => auth.credentials.token, :secret => auth.credentials.secret).first_or_initialize authorization.profile_page = auth.info.urls.first.last unless authorization.persisted? if authorization.user.blank? user = current_user.nil? ? User.where('email = ?', auth['info']['email']).first : current_user if user.blank? user = User.new user.skip_confirmation! user.password = Devise.friendly_token[0, 20] user.fetch_details(auth) user.save end authorization.user = user authorization.save end authorization.user end def fetch_details(auth) self.name = auth.info.name self.email = auth.info.email self.photo = URI.parse(auth.info.image) end 

最后,您需要覆盖Devise控制器的方法

 class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def all user = User.from_omniauth(env['omniauth.auth'], current_user) if user.persisted? sign_in user flash[:notice] = t('devise.omniauth_callbacks.success', :kind => User::SOCIALS[params[:action].to_sym]) if user.sign_in_count == 1 redirect_to first_login_path else redirect_to cabinet_path end else session['devise.user_attributes'] = user.attributes redirect_to new_user_registration_url end end User::SOCIALS.each do |k, _| alias_method k, :all end end 

如果您需要一些供应商,例如Twitter,您需要覆盖Twitter方法,因为它不提供用户电子邮件,您应该以其他方式保存它的凭证。

你也应该对路线做一些改变

 devise_for :users, :controllers => { :omniauth_callbacks => 'users/omniauth_callbacks', } 

你应该试试这个gem。 https://github.com/AlexanderZaytsev/domp快速,易于集成。 我在大约30米处有一个工作设置。

在你的初始化者尝试做这样的事情

 #config/initializers/devise.rb #provider1 config.omniauth :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_SECRET'], :site => 'https://graph.facebook.com/', :authorize_path => '/oauth/authorize', :access_token_path => '/oauth/access_token', :scope => 'email, user_birthday, read_stream, read_friendlists, read_insights, read_mailbox, read_requests, xmpp_login, user_online_presence, friends_online_presence, ads_management, create_event, manage_friendlists, manage_notifications, publish_actions, publish_stream, rsvp_event, user_about_me, user_activities, user_birthday, user_checkins, user_education_history, user_events, user_groups, user_hometown, user_interests, user_likes, user_location, user_notes, user_photos, user_questions, user_relationships, user_relationship_details, user_religion_politics, user_status, user_subscriptions, user_videos, user_website, user_work_history' #provider2 config.omniauth :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'], :scope => { :secure_image_url => 'true', :image_size => 'original', :authorize_params => { :force_login => 'true' } } #provider3 config.omniauth :google_oauth2, ENV["GOOGLE_KEY"], ENV["GOOGLE_SECRET"]