2012-02-27 3 views
3

github에 표시된 예제 코드는 여러 로그인 방법 (oauth의 전체 지점)을 허용하도록 확장 된 경우 중복 계정을 만드는 것처럼 보입니다. 여기 snipit에서 login_from()이 성공하지 못하면 create_from()이 호출된다는 것을 알 수 있습니다.레일즈 Sorcery 버그? 중복 사용자 계정 생성

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의 소스 코드를 조사. 사용자 계정 레코드가 이미있는 경우 이는 올바르지 않습니다.

내 질문 : 페이스 북 이외의 방법으로 사용자 계정을 만든 경우 첫 번째 페이스 북에서 어떤 소셜 메신저를 호출해야합니다. login_from이 실패하고 create_from이 중복 된 usser 레코드를 생성합니까?

+0

이것은 버그는 아니지만 찾고있는 기능 (기존 사용자에게 인증 추가)은 현재 Sorcery에서 지원하지 않는 것 같습니다. 그걸 앱에 적용하는 방법의 예가있는 사람의 이야기를 듣고 싶습니다. – Andrew

+0

@Dan 행운이 있나요? –

+0

@ChristianFazzini 우리는 운이 좋았습니다. 이 스레드에 우리의 접근 방식을 게시했습니다. –

답변

2

몇 가지 요청이이 질문에 대한 답변으로 끝났으므로 Andy Mejia가 결국이 질문에 대한 답을 얻었습니다.

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 

나는 희망이 솔루션은 다른 사람에게 도움이 될 것입니다 : 나는 또한 우리의 컨트롤러 로직을 포함하고 맥락에서이 코드를 표시하려면

# 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=>"[email protected]", :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 

: 우리는 다음과 같은 기능을 적응 마법 내에서 소스를 사용 .

0

같은 문제가 발생했습니다. 나는 마법을 통해 직접 해결책을 발견하지 않은 동안, 나는이 작동하는 것 같다 다음을했다 :

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

이 teqnique 당신은 사용자 모델에서 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과 호환됩니다.

3

def create_and_validate_from(provider)을 사용할 수 있습니다.

사용자 이메일/사용자 이름이 이미 존재하는지 확인합니다. 그것이 사실이라면 세션에 정보를 저장하고 등록 양식으로 렌더링 할 수 있습니다.

그리고 계정에 일부 제공 업체를 추가하려면 def add_provider_to_user(provider)을 사용할 수 있습니다.

+0

이 답변을 보증 할 수는 없습니다. 솔루션을 구축 할 때 존재하지 않는다고 생각합니다. 정확하다면이 접근법이 분명히 우수합니다. –