2014-11-02 72 views
3

我已经花了最后一天的时间来解决这个问题,这使我疯了。Rails devise omniauth-facebook .persisted?返回false

昨晚,我在我的网站上登录了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?是返回false。我用Heroku 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)返回的东西(这不应该是因为我的数据库是空的)。是否可能有一个索引存在于我的数据库之外的某个地方,这就是它正在搜索的内容?

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

Edit 1

刚试过以下,它的作品,这使得我更加糊涂比以往任何时候:

  1. 从我的Facebook帐户删除该应用程序为我使用该帐户进行测试
  2. 尝试使用脸书登录并使用:scope => 'user_birthday'离开。Facebook列出了所需的权限为your public profile and birthday。接受并返回到我的网站,失败按上述(即使信息肯定被发回)
  3. 删除:scope => 'user_birthday'并尝试再次登录Facebook使用。定向到Facebook,其中列出了要求为your public profile and email address的权限。接受并获得指导回到现在有效的网站,并且还有用户的生日存储和访问,因为我从上面的第2号的facebook获得了许可。

我完全不知所措现在

+0

什么是你的生日列的类型(用户表)? – mohameddiaa27 2014-11-03 00:19:28

+0

字符串。根据我的编辑,它是保存和访问步骤3 – 2014-11-03 00:24:07

回答

3

要了解的对象没有被保存原因。你需要把错误。

puts @user.errors.to_a 

,并检查的auth

puts request.env["omniauth.auth"] 
+1

非常感谢这个mohameddiaa27。我不知道如何调试.first_or_create(),但是.errors.to_a()完全可以。问题是当我要求user_birthday时,facebook停止发送用户电子邮件出于某种原因,并引发错误'电子邮件不能为空'。如果我还要求user_birthday,我想我必须明确地将其添加到范围。再次感谢。 – 2014-11-03 09:39:26

0

我有同样的问题的内容,然后按照上面的答案,我把“@ user.errors.to_yaml”在我的代码,我看到那里是我发现的错误。

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

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

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