Rails设计omniauth-facebook .persisted?返回假

时间:2014-11-02 22:31:08

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

我花了最后一天试图解决这个问题并且让我疯狂。

昨晚,我在我的网站上登录facebook并正在检索基本的用户信息。当我将:scope => 'user_birthday'添加到config/initializers/omniauth.rb时,问题就出现了,现在看起来像这样

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook, "APP_ID", "APP_SECRET", :scope => 'user_birthday'
end

作为参考,我已从config.omniauth :facebook, "APP_ID", "APP_SECRET"

中删除了行config/initializers/devise.rb

我花了好几个小时试图让它工作但最终不得不放弃。然后今天早上我再次运行它并且它有效。喜出望外,我试图向:scope添加另一个参数,但现在整个事情再次被打破。如果我删除:scope,我可以让它工作,但是每当我把它放回去时它都会失败(即使它只是:scope => 'user_birthday',就像我今天早上第一件工作一样)。

为了找到问题,我将调试代码放在omniauth_callbacks_controller.rb中,它现在看起来像:

class Users::OmniauthCallbacksController < 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"])
        puts "start before persist debug"
        puts @user.birthday
        puts @user.persisted?
        puts "end before persist debug"

    if @user.persisted?         
            puts "Start persisted debug"
            puts request.env["omniauth.auth"]
            puts "End debug"            
      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"]
            puts "Start unpersisted debug"
            puts request.env["omniauth.auth"]
            puts "End debug"
      redirect_to new_user_registration_url
    end
  end
end

此调试清楚地显示facebook正在返回必要的信息,但应用程序失败,因为.persisted?返回false,因此我被重定向到new_user_registration页面,该页面返回以下内容: -

NoMethodError in Devise::Registrations#new
Showing /home/action/workspace/cloudapp/app/views/devise/shared/_links.html.erb where line #23 raised:

undefined method `omniauth_authorize_path' for #<#<Class:0x007f3aeffff038>:0x007f3aefffdf08>

我不能为我的生活弄清楚为什么.persisted?返回false。我使用Herrous postgresql数据库使用Nitrous.io进行开发。我已通过运行

确认数据库中没有用户
rails c
User.all

返回:

  User Load (89.4ms)  SELECT "users".* FROM "users"                                                                                                                                                                                                     
=> #<ActiveRecord::Relation []> 

我感觉问题出现在models/user.rb但是我无法弄清楚如何调试它以查看它是否找到了用户,因此没有持久或尝试创建用户失败。有没有人知道一种简单的调试方法?

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]
        user.name = auth.info.name   # assuming the user model has a name
        user.birthday = auth.extra.raw_info.birthday
        # user.image = auth.info.image # assuming the user model has an image
    end
end

我已经完成了大约50次并且接近放弃了。

我唯一能想到的是where(provider: auth.provider, uid: auth.uid)正在返回一些东西(它不应该因为我的数据库是空的)。是否可能存在一个存在于我的数据库之外某处的索引以及它正在搜索的内容?

请为了我的理智,任何人都可以帮忙吗?如果您需要更多信息,我很乐意提供

  

修改1

尝试了以下内容,它让我比以前更加困惑:

  1. 从我的Facebook帐户中删除应用,因为我正在使用该帐户进行测试
  2. 尝试使用留下:scope => 'user_birthday'的Facebook登录.Facebook列出了your public profile and birthday所需的权限。接受并发送回我的网站,如上所述失败(即使信息肯定被发回)
  3. 删除:scope => 'user_birthday'并尝试再次使用Facebook登录。转到facebook,其中列出了your public profile and email address所需的权限。接受并被定向回现在正常工作的网站,并且还存储和访问用户生日,因为我从上面的第2号获得了facebook的支持。
  4. 我现在完全不知所措

3 个答案:

答案 0 :(得分:4)

了解为什么没有保存对象。您需要输入错误。

puts @user.errors.to_a

并检查auth

的内容
puts request.env["omniauth.auth"]

答案 1 :(得分:0)

我遇到了同样的问题,并按照上面的答案,我在我的代码上放了“@ user.errors.to_yaml”,我发现错误在哪里,我找到了。

我也在使用“设计”和“omniauth-facebook”。 omn​​iauth-facebook的默认范围是“email”。但是,我在范围内添加了属性:“user_about_me,user_status,user_location,user_birthday,user_photos”。我需要在范围上添加“EMAIL”以设计用于创建“用户”。当我看到我的错误时,我发现了这一点:“电子邮件不是空白”。

要点: 如果您在范围上插入属性,请始终输入“email”。

答案 2 :(得分:0)

Facebook并不总是为用户

返回电子邮件

来自facebook开发者https://developers.facebook.com/bugs/298946933534016

一些可能的原因:

  • 帐户中没有电子邮件地址
  • 帐户中未确认电子邮件地址
  • 帐户中未经过验证的电子邮件地址
  • 用户输入了一个安全检查点,要求他们再次确认 他们的电子邮件地址,他们还没有这样做
  • 用户的电子邮件地址无法访问

您还需要“电子邮件”扩展权限,即使对于拥有有效,已确认,可访问的电子邮件地址的用户也是如此。

用户输入了一个安全检查点,要求他们重新确认他们的电子邮件地址,但他们尚未这样做 用户的电子邮件地址无法访问

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    def facebook
        puts request.env["omniauth.auth"]   #  check if request.env["omniauth.auth"] is provided an email
        if request.env["omniauth.auth"].info.email.present?
         @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
        else
          redirect_to new_user_registration_url, notice: "Can't sign in to your #{request.env["omniauth.auth"].provider} account. Try to sign up."
        end
    end
  end