2014-01-10 2 views
3

Я использовал программу, чтобы пользователи могли зарегистрироваться и войти на сайт. Я также использовал omniauth-facebook, чтобы пользователи могли войти в систему со своими учетными записями в facebook. Тем не менее, люди, которые впервые зарегистрировались с тем же электронным письмом, что и их электронная почта, не могут войти в свою учетную запись на facebook. Я хочу использовать как регистрацию в 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 
+0

Вы хотите использовать как логин facebook, так и придумать (email/pass) или только один из них ?. Я могу ответить на ваш вопрос, основываясь на этом - спасибо –

+0

@matrixtheone Я хочу использовать как facebook login, так и разработать регистрацию. спасибо! – achilleo

ответ

0

Вы можете добавить пользовательскую проверку для поля электронной почты в модели пользователя как

email_regex = /\A[\w+\-.][email protected][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."} 
+0

Как это решить проблему в любом случае? – phoet

+0

в любое время, когда вы хотите сохранить запись пользователя, она будет проверяться в электронной почте, которая уже существует в базе данных или нет. –

1

Вы может легко сделать это следующим образом:

  1. Создать другую модель под названием Authorization с атрибутами:

    provider:string, uid:string, user_id:integer 
    
  2. Теперь пользователь будет связан с авторизацией следующим образом:

    class User 
        has_many :authorizations 
        ... 
    end 
    
  3. Всякий раз, когда происходит facebook Войти, проверить с разрешениями чтобы увидеть, присутствует ли запись. Если не создать его и связать с моделью пользователя (путем поиска по идентификатору электронной почты).

  4. Получите правильный объект пользователя и войдите в него.

Источник: http://net.tutsplus.com/tutorials/ruby/how-to-use-omniauth-to-authenticate-your-users/

+0

спасибо, я решил проблему, основанную на вашем решении. БОЛЬШАЯ ПОМОЩЬ! – achilleo

0

Я задал этот вопрос и просто нашел пути выхода на основе anwser matrixtheone (в самом деле большую помощь) и в этом блоге. 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 
+0

Имейте в виду, что существует проблема безопасности с такой логикой входа. Вы можете ставить учетные записи пользователей таким образом! – phoet

Смежные вопросы