Facebook Omniauth的问题,设计Ruby on Rails

时间:2017-06-13 08:24:01

标签: ruby-on-rails devise omniauth-facebook

我已经搜索了这些页面数周寻找答案。我是Ruby的新手,我遵循了一个教程,并且能够成功完成它并没有大惊小怪。我的问题是,当我决定通过使用Omniauth gem对Facebook用户进行身份验证时,除了设计完美的设计宝石之外,还要为我的应用添加更多功能。

我几乎知道解决方案对于受过训练的人来说很简单,但我不知所措,因为我在这个网站上尝试了很多建议,而其他人则取得了不同程度的成功。

我目前的问题是,只要用户尝试使用Facebook登录,用户就会通过身份验证,但会被重定向到注册页面。我上周在某个时间摆弄并且能够成功登录但只是一次并且随后被重定向到注册页面。

我需要的方案是:

如果用户点击使用Facebook链接登录,他们应该被重定向到Facebook进行身份验证,然后发送回我的Ruby应用程序,并将email,first_name,last_name的值添加到该用户的User表中

对于回归用户, 应该检查所有数据库值,并且用户自动登录而不用大惊小怪。

我还想要一个电子邮件唯一约束,以确保我们没有多个人使用相同的电子邮件。

我真的很感激某些方向,我在哪里弄错了。就像我上面提到的那样,我在这个领域是一个全新的角色,因为我主要使用IT基础设施。

请参阅下面的代码:

callbacks_controller.rb

 class CallbacksController < Devise::OmniauthCallbacksController
   def facebook
   # You need to implement the method below in your model (e.g. 
   app/models/user.rb)
@user = User.from_omniauth(request.env["omniauth.auth"])

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

def failure
  redirect_to root_path
end
def def     redirect_to root_path     结束    端

user.rb

 class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable, :omniauthable
has_many :reviews, dependent: :destroy

#validates :first_name, :last_name, presence: true
devise :omniauthable, :omniauth_providers => [:facebook]


 def self.from_omniauth(auth)
  where(email: auth.info.email).first_or_initialize.tap do |user|
  user.email = auth.info.email
  user.password = Devise.friendly_token[6,20]
  user.first_name = auth.info.first_name
  user.last_name = auth.info.last_name
  user.save
  end


  end

  end

  def self.new_with_session(params, session)
   super.tap do |user|
  if data = session["devise.facebook_data"] && session["devise.facebook_data"]
    ["extra"]["raw_info"]
    user.email = data["email"] if user.email.blank?
    user.first_name = data["first_name"] if user.first_name.blank?
    user.last_name = data["last_name"] if user.last_name.blank?
    end
   end
  end

的routes.rb

   Rails.application.routes.draw do

   devise_for :users, :controllers => { :omniauth_callbacks => "callbacks"}
   resources :hospitals do
   collection do
   get 'search'
   end
   resources :reviews, except: [:show, :index]
    end



    get 'pages/Hospitals'

    get 'pages/Labs'

    get 'pages/Doctors'

    get 'pages/about'

    get 'pages/contact'

    root'hospitals#index'



   # For details on the DSL available within this file, see 
    http://guides.rubyonrails.org/routing.html
    end

控制台响应

 Started GET "/users/auth/facebook" for ::1 at 2017-06-13 14:02:29 +0100
 I, [2017-06-13T14:02:29.142018 #8385]  INFO -- omniauth: (facebook) Request 
 phase initiated.
 Started GET "/users/auth/facebook" for ::1 at 2017-06-13 14:02:29 +0100
 I, [2017-06-13T14:02:29.488425 #8385]  INFO -- omniauth: (facebook) Request 
 phase initiated.
 Started GET "/users/auth/facebook/callback
 code=AQAJ33qxsDJhSh2fKc8YH9YANZwK2BagO3fotR22iw3
 cOeTN5G2HSvXbOioiwaQmwrZB3EEZKZBWlBAK4c
 RVyddoG8oaeLQfEXjA0FPOvZtpw0XiuBGwOJIh7YaDSjt7O33Dn2mB7Vlu2YUaT-
 DxlY3ioOVhNx8ymCE6TMGJx0slL-NvMB8b52IHSheMvPYTcMAoj2WXPgrLK8aH0eox_
 7VbD8zaV0QFeJxqask3gaU4GTkGI50liO2SdF
 T9fyFVWTgfORNP0yhwoH3HNlMGIznqSqbRGB43d
 2qULNHglH6exDMCzgpyhD3Bmi2lxzcLc10"
  for ::1 at 2017-06-13 14:02:29 +0100
 I, [2017-06-13T14:02:29.731093 #8385]  INFO -- omniauth: (facebook) Callback 
 phase initiated.
 Processing by CallbacksController#facebook as HTML
 Parameters: 
 {"code"=>"AQAJ33qxsDJhSh2fKc8YH9YANZwK2BagO3
 fotR22iw3cOeTN5G2HSvXbOioiwaQmwrZB3EEZK
 ZBWlBAK4cRVyddoG8oaeLQfEXjA0FPOvZtpw0XiuBGwOJIh7YaDSjt7O33Dn2mB7Vlu2YUaT-
 DxlY3ioOVhNx8ymCE6TMGJx0slL-
 NvMB8b52IHSheMvPYTcMAoj2WXPgrLK8aH0eox_
 7VbD8zaV0QFeJxqask3gaU4GTkGI50liO2SdFT9fy
 FVWTgfORNP0yhwoH3HNlMGIznqSqbRGB43d2qULNHglH6exDMCzgpyhD3Bmi2lxzcLc10"}
  User Load (0.3ms)  SELECT  "users".* 
  FROM "users" WHERE "users"."email" IS NULL 
  ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
  (0.2ms)  begin transaction
  (0.1ms)  rollback transaction
  Redirected to http://localhost:3000/users/sign_up
  Completed 302 Found in 265ms (ActiveRecord: 0.6ms)

新的控制台响应

  User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."provider" = ? 
  AND 
  "users"."uid" = ? ORDER BY "users"."id" ASC LIMIT ? [["provider", 
  "facebook"], ["uid", "104903843446146"], ["LIMIT", 1]] (0.1ms) begin 
  transaction (0.1ms) rollback transaction Redirected to 
  localhost:3000/users/sign_up

1 个答案:

答案 0 :(得分:0)

尝试以下代码:

def facebook
    @user = User.from_omniauth(request.env["omniauth.auth"])
      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

模型

  def self.from_omniauth(auth)
      where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
        user.email = auth.info.email
        user.password = Devise.friendly_token[0,20]
      end
    end