3

github に示されているソーサリー コードの例は、複数のサインイン方法を許可するように拡張すると、重複するアカウントを作成するように見えます (これが oauth の要点です)。ここのスニピットで、login_from() が成功しない場合に create_from() が呼び出されることがわかります。

GitHub AT https://github.com/NoamB/sorcery-example-app/blob/master/app/controllers/oauths_controller.rb

def callback
provider = params[:provider]
begin
if @user = login_from(provider)
  redirect_to root_path, :notice => "Logged in from #{provider.titleize}!"
else
  begin
    @user = create_from(provider)

すべてのケースで create_from のソース コードを調査すると、新しいユーザー アカウント レコードが作成されます。ユーザー アカウント レコードが既に存在する場合、これは正しくありません。

私の質問: ユーザー アカウントが Facebook 以外の方法で作成された場合、最初の Facebook 接続でどのソーサリー メソッドを呼び出す必要がありますか。login_from は失敗し、create_from は重複するユーザー レコードを生成しますか?

4

3 に答える 3

3

def create_and_validate_from(provider)を使用できます。

ユーザーの電子メール/ユーザー名が既に存在するかどうかを検証します。その場合、彼は情報をセッションに保存し、登録フォームにレンダリングできます。

また、アカウントにプロバイダーを追加したい場合は、def add_provider_to_user(provider)を使用できます。

于 2012-09-13T11:49:00.530 に答える
2

この質問への回答を求めるリクエストがいくつか寄せられたので、私のチームの一部である Andy Mejia がこの質問に対して最終的にたどり着いた回答を提供します。ソーサリー内のソースを使用して、次の機能を適応させました。

# 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

このソリューションが他の人に役立つことを願っています。

于 2012-09-30T08:43:57.220 に答える
0

私は同じ問題に遭遇しました。Sorceryを介した直接的な解決策は見つかりませんでしたが、次のように機能しました。

    @user = create_from(params[:provider]) do |user|
      User.where(:twitter_id => user.twitter_id).first.blank?
    end

twitter_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ます。

于 2012-08-30T22:52:10.487 に答える