4

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

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

我现在完全不知所措

4

3 回答 3

4

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

puts @user.errors.to_a

并检查内容auth

puts request.env["omniauth.auth"]
于 2014-11-03T00:45:19.493 回答
0

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

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

摘要:如果您在作用域上插入属性,请始终输入“电子邮件”。

于 2015-03-11T02:08:29.480 回答
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
于 2017-10-19T09:01:41.973 回答