如何允许用户使用注册帐户和Facebook帐户登录?

时间:2014-01-10 06:47:13

标签: ruby-on-rails devise gem omniauth

我使用了devise来允许用户在站点内注册和登录。我还使用omniauth-facebook允许用户使用他们的Facebook帐户登录。但是,首先使用与facebook-email相同的电子邮件注册的人无法使用他们的Facebook帐户登录。我想同时使用facebook登录和网站注册。

这是我的user.rb

class User < ActiveRecord::Base

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

  def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
    user = User.where(:provider => auth.provider, :uid => auth.uid).first
    unless user
      user = User.create(name:auth.extra.raw_info.name,
                         provider:auth.provider,
                         uid:auth.uid,
                         email:auth.info.email,
                         password:Devise.friendly_token[0,20]
                         )
    end
    user
  end
end

和omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    @user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)

    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end
end

3 个答案:

答案 0 :(得分:1)

您可以通过以下方式轻松完成此操作:

  1. 使用以下属性创建另一个名为Authorization的模型:

    provider:string, uid:string, user_id:integer
    
  2. 现在,用户将与授权相关联,如下所示:

    class User
      has_many :authorizations
      ...
    end
    
  3. 每当Facebook登录时,请检查授权模型以查看是否存在记录。如果没有创建它并将其链接到用户模型(通过电子邮件ID搜索)。

  4. 获取正确的用户对象并使用它进行登录。

  5. 来源:http://net.tutsplus.com/tutorials/ruby/how-to-use-omniauth-to-authenticate-your-users/

答案 1 :(得分:1)

我问了这个问题,并找到了基于matrixtheone的anwser(非常好的帮助)和本博客的方法。 http://www.orhancanceylan.com/rails-twitter-and-facebook-authentications-with-omniauth-and-devise/

这是代码。如果出现问题,请弄清楚

def facebook
  omni = request.env["omniauth.auth"]
  authentication = Authentication.find_by_provider_and_uid(omni['provider'],omni['uid'])

  if authentication
    flash[:notice] = "Logged in Successfully"
    sign_in_and_redirect User.find(authentication.user_id)
  elsif user = User.find_by(email: omni['extra']['raw_info'].email)
    user.authentications.create!(provider:omni['provider'], 
                        uid:omni['uid'])
    flash[:notice] = "Authentication for registered user is successful"
    sign_in_and_redirect user
  else
    user = User.new
    user.password = Devise.friendly_token[0,20]
    user.email = omni['extra']['raw_info'].email
    user.authentications.build(provider:omni['provider'], 
                        uid:omni['uid'])
    if user.save
      flash[:notice] = "Logged in."
      sign_in_and_redirect User.find(user.id)
    else
      session[:omniauth] = omni.except('extra')
      redirect_to new_user_registration_path
    end
  end
end

答案 2 :(得分:0)

您可以在用户模型中为电子邮件字段添加自定义验证,例如

email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, :presence =>{:message => "An email address must be entered."},
                    :format => { :with => email_regex , :message => "The email address is not valid." },
                    :uniqueness => { :case_sensitive => false,  :message => "The email address is already used."}