Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 3 Rails魔法虫?创建重复的用户帐户_Ruby On Rails 3_Authentication_Sorcery - Fatal编程技术网

Ruby on rails 3 Rails魔法虫?创建重复的用户帐户

Ruby on rails 3 Rails魔法虫?创建重复的用户帐户,ruby-on-rails-3,authentication,sorcery,Ruby On Rails 3,Authentication,Sorcery,github上显示的示例巫术代码在我看来似乎创建了重复的帐户,如果它被扩展为允许多个登录方法(这是oauth的全部要点)。您可以在这里的snipit中看到,如果登录\u from()失败,将调用create\u from() GITHUB AT AT 调查create_from的源代码在所有情况下都将创建一个新的用户帐户记录。如果用户帐户记录已经存在,则这是不正确的 我的问题是:如果用户帐户是通过facebook以外的其他方式创建的,那么在第一个facebook连接上应该调用什么巫术方法。登录将

github上显示的示例巫术代码在我看来似乎创建了重复的帐户,如果它被扩展为允许多个登录方法(这是oauth的全部要点)。您可以在这里的snipit中看到,如果登录\u from()失败,将调用create\u from()

GITHUB AT AT

调查create_from的源代码在所有情况下都将创建一个新的用户帐户记录。如果用户帐户记录已经存在,则这是不正确的


我的问题是:如果用户帐户是通过facebook以外的其他方式创建的,那么在第一个facebook连接上应该调用什么巫术方法。登录将失败,创建将生成重复的苏联记录?

我遇到了同样的问题。虽然我没有通过巫术找到直接的解决办法,但我做了以下似乎有效的事情:

    @user = create_from(params[:provider]) do |user|
      User.where(:twitter_id => user.twitter_id).first.blank?
    end
此技术要求用户模型中有
twitter\u id
。您也可以通过认证模型以另一种方式来实现。例如:

    @user = create_from(params[:provider]) do |user|
      Authentication.where(:uid => user.twitter_id).first.blank?
    end
如果块返回false,则它不会创建用户。避免任何重复

注意,
create_from
的块不适用于
0.7.12
。它适用于您可以使用的
0.7.13

它将验证用户的电子邮件/用户名是否已存在。如果是真的,他会将信息存储到会话中,并可以呈现到注册表中


如果您希望向您的帐户中添加一些提供商,您可以使用。

已经有几个人要求回答这个问题,因此我提供了我团队的安迪·梅加最终就这个问题得出的答案。我们使用巫术中的来源来调整以下功能:

# Returns the hash that contains the information that was passed back from Facebook.
# It only makes sense to call this method on the callback action.
#
# Example hash:
# {:user_info=>{:id=>"562515238", :name=>"Andrés Mejía-Posada", :first_name=>"Andrés", :last_name=>"Mejía-Posada", :link=>"http://www.facebook.com/andmej", :username=>"andmej", :gender=>"male", :email=>"andmej@gmail.com", :timezone=>-5, :locale=>"en_US", :verified=>true, :updated_time=>"2011-12-31T21:39:24+0000"}, :uid=>"562515238"}
def get_facebook_hash
  provider = Rails.application.config.sorcery.facebook
  access_token = provider.process_callback(params, session)
  hash = provider.get_user_hash
  hash.merge!(:access_token => access_token.token)
  hash.each { |k, v| v.symbolize_keys! if v.is_a?(Hash) }
end


# Method added to the User Account model class
def update_attributes_from_facebook!(facebook_hash)
  self.first_name             = facebook_hash[:user_info][:first_name] if self.first_name.blank?
  self.last_name              = facebook_hash[:user_info][:last_name]  if self.last_name.blank?
  self.facebook_access_token  = facebook_hash[:access_token]
  self.email                ||= facebook_hash[:user_info][:email]
  unless facebook_authentication?
    authentications.create!(:provider => "facebook", :uid => facebook_hash[:uid])
  end
  self.build_facebook_profile if facebook_profile.blank?
  save!
  self.facebook_profile.delay.fetch_from_facebook! # Get API data
end
为了在上下文中显示这些代码,我还包括来自控制器的逻辑:

def callback
   provider = params[:provider]
   old_session = session.clone # The session gets reset when we login, so let's backup the data we need
   begin
     if @user = login_from(provider)   # User had already logged in through Facebook before
       restore_session(old_session)   # Cleared during login
     else
       # If there's already an user with this email, just hook this Facebook account into it.
       @user = UserAccount.with_insensitive_email(get_facebook_hash[:user_info][:email]).first
       # If there's no existing user, let's create a new account from scratch.
       @user ||= create_from(provider) # Be careful, validation is turned off because Sorcery is a bitch!
       login_without_authentication(@user)
     end
   @user.update_attributes_from_facebook!(get_facebook_hash)
   rescue ::OAuth2::Error => e
     p e
     puts e.message
     puts e.backtrace
     redirect_to after_login_url_for(@user), :alert => "Failed to login from #{provider.titleize}!"
     return
   end
   redirect_to after_login_url_for(@user)
 end

我希望此解决方案对其他人有帮助。

这不是一个bug,但您正在寻找的功能(向现有用户添加身份验证)目前似乎并不真正受巫术支持。我很想听到任何有关于如何将其修补到应用程序的例子的人的声音。@Dan这方面有什么好运气吗?@ChristianFazzini我们确实有运气。我在这个帖子中发布了我们的方法。我不能保证这个答案——我不相信在我们构建解决方案时它是存在的。如果准确的话,这种方法显然是优越的。
def callback
   provider = params[:provider]
   old_session = session.clone # The session gets reset when we login, so let's backup the data we need
   begin
     if @user = login_from(provider)   # User had already logged in through Facebook before
       restore_session(old_session)   # Cleared during login
     else
       # If there's already an user with this email, just hook this Facebook account into it.
       @user = UserAccount.with_insensitive_email(get_facebook_hash[:user_info][:email]).first
       # If there's no existing user, let's create a new account from scratch.
       @user ||= create_from(provider) # Be careful, validation is turned off because Sorcery is a bitch!
       login_without_authentication(@user)
     end
   @user.update_attributes_from_facebook!(get_facebook_hash)
   rescue ::OAuth2::Error => e
     p e
     puts e.message
     puts e.backtrace
     redirect_to after_login_url_for(@user), :alert => "Failed to login from #{provider.titleize}!"
     return
   end
   redirect_to after_login_url_for(@user)
 end