我花了好几天时间在设计和omniauth上观看RailsCasts,然后通过相关教程来设置使用这些gems的身份验证系统。我认为RailsCasts已经过时了,试图用其他教程修补差距会产生各种各样的问题。
请有人建议我可以使用当前的教程作为实现此系统的基础。我有单独的用户和身份验证模型(用户有许多身份验证)。
我真的很喜欢在rails 4上使用设计和omniauth(使用CanCan的功能),但是在试图找到基本设置(使用psql作为数据库)时,我正在撕裂我的头发。
答案 0 :(得分:30)
要将Devise与多个身份验证提供程序一起使用,您需要再增加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',
}
答案 1 :(得分:3)
你应该试试这个宝石。 https://github.com/AlexanderZaytsev/domp 快速,易于集成。我在大约30米处进行了工作设置。
答案 2 :(得分:2)
在初始化程序中尝试做这样的事情
#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"]