问题描述
我花了几天时间在设计和全方位观看RailsCast,然后通过相关教程设置使用这些宝石的身份验证系统。我认为RailsCast已经过时了,尝试用其他教程来弥补差距,正在创造各种各样的问题。
I have spent days watching the RailsCasts on devise and omniauth and then going through related tutorials for setting up an authentication system that uses these gems. I think the RailsCasts are out of date and trying to patch the gaps with other tutorials is creating all kinds of issues.
请任何人建议我可以使用的当前教程作为实施这一制度的基础。我有单独的用户和身份验证模型(用户有许多身份验证)。
Please can anyone suggest a current tutorial that I can use as a basis for implementing this system. I have separate user and authentications models (with users having many authentications).
我真的很想在rails 4上使用devise和omniauth(使用CanCan的能力),但是我试图找到一个基本的设置(使用psql作为数据库)
I'd really like to use devise and omniauth (with CanCan for abilities) on rails 4 but am tearing my hair out in trying to find a basic setup (using psql as a database).
推荐答案
要使用Devise与多个验证服务提供商,您需要另外一个模型 - 授权
To use Devise with multiple auth providers you need 1 more model - Authorization
#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
strong>用户模型
There is code for User model
#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控制器的方法
And at the end you need to override methods for Devise controller
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方法,因为它不提供用户电子邮件,您应该以其他方式保存它的凭据。
If you need some for providers, e.g. Twitter you need to override twitter method, because it doesn't provide user email and you should save it's credentails in some other way.
还应该在路由中进行一些更改
Also you should make some changes in routes
devise_for :users,
:controllers => {
:omniauth_callbacks => 'users/omniauth_callbacks',
}
这篇关于Rails 4,Devise,Omniauth(多个提供商)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!