【问题标题】:Rails devise omniauth-facebook .persisted? returning falseRails 设计了omniauth-facebook .persisted?返回假
【发布时间】:2014-11-02 22:31:08
【问题描述】:

我花了最后一天试图解决这个问题,这让我发疯了。

昨晚,我在我的网站上使用 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/initializers/devise.rb 中删除了config.omniauth :facebook, "APP_ID", "APP_SECRET" 行

我花了几个小时试图让它发挥作用,但最终不得不放弃。然后今天早上我再次运行它并且它起作用了。喜出望外,我试图在: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? 返回错误。我正在使用 Nitrous.io 进行 Heroku postgresql 数据库的开发。我已经通过运行确认数据库中没有用户

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 =&gt; 'user_birthday' 的Facebook 登录。Facebook 将寻求的权限列为your public profile and birthday。接受并返回我的网站,但按照上述失败(即使信息肯定会被发回)
  3. 删除 :scope =&gt; 'user_birthday' 并尝试再次使用 facebook 登录。定向到 facebook,其中列出了your public profile and email address 寻求的许可。接受并返回到现在可以正常工作的网站,并且还存储和访问用户生日,因为我从上面的第 2 点获得了来自 facebook 的许可。

我现在完全不知所措

【问题讨论】:

  • 你的生日列的类型是什么(在用户表中)?
  • 字符串。根据我的编辑,它在第 3 步中保存和访问

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


【解决方案1】:

找出对象未保存的原因。您需要输入错误。

puts @user.errors.to_a

并检查auth的内容

puts request.env["omniauth.auth"]

【讨论】:

  • 非常感谢这个 mohameddiaa27。我不知道如何调试 .first_or_create() 但你的 .errors.to_a() 做得很好。问题是当我请求 user_birthday 时,facebook 出于某种原因停止发回用户电子邮件,并抛出错误“电子邮件不能为空白”。如果我还请求 user_birthday,我想我必须将它明确添加到范围中。再次感谢。
【解决方案2】:

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

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

总结: 如果您在范围上插入属性,请始终输入“电子邮件”。

【讨论】:

    【解决方案3】:

    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
    

    【讨论】:

      猜你喜欢
      • 2016-06-10
      • 2013-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-23
      • 2012-03-05
      相关资源
      最近更新 更多