Rails 使用 Devise 和 Omniauth 的社交登录 (Facebook) - 未定义的方法“持续存在?” nil:NilClass
Rails social login ( Facebook) with Devise and Omniauth - undefined method `persisted?' for nil:NilClass
我在这里查找了一些问题和答案,但找不到解决我的问题的方法。我不断收到未定义的方法“持续存在?” nil:NilClass 尝试使用 Facebook 登录时。这是我的 Omniauth 回调控制器:
class OmniauthCallbacksController < ApplicationController
skip_before_filter :authenticate_user!
def provides_callback_for
user = User.from_omniauth(env["omniauth.auth"])
if user.persisted?
flash[:notice] = "You have signed in!"
sign_in_and_redirect(user)
else
session['devise.user_attributed'] = user.attributes
redirect_to new_user_registration_url
end
end
alias_method :facebook, :provides_callback_for
end
授权模型:
class Authorization < ActiveRecord::Base
belongs_to :user
after_create :fetch_details_from_facebook
def fetch_details_from_facebook
graph = Koala::Facebook::API.new(self.token)
facebook_data = graph.get_object("me")
self.username = facebook_data["username"]
self.save
end
end
和我的用户模型:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
has_many :friends
has_many :notifications
has_many :authorizations
validates_presence_of :name
validates :email, :presence => true, email_format: {message: "Please enter valid e-mail!"}
validates :phone, phone: true, presence: true
validates :birthday, :timeliness => {:on_or_before => lambda { Date.current }, :type => :date}
def self.new_with_session(params, session)
if session["devise.user_attributes"]
new(session["devise.user_attributes", without_protection: true]) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
def self.from_omniauth(auth)
authorization = Authorization.where(:provider => auth.provider, :uid => auth.uid.to_s, :token => auth.credentials.token, :secret => auth.credentials.secret).first_or_initialize
if authorization.user.blank?
user = User.where('email = ?', auth["info"]["email"]).first
if user.blank?
user = User.new
user.password = Devise.friendly_token[0, 10]
user.name = auth.info.name
user.email = auth.info.email
user.image = auth.info.image
user.save
end
authorization.username = auth.info.nickname
authorization.user_id = user.id
authorization.save
end
authorization.user
end
end
我已经尝试了很多方法,但仍然出现该错误。谁能指出我正确的方向?非常感谢非常感谢!
已更新
请确认您收到的是来自 Facebook 的电子邮件。
未经批准,Facebook 不提供 EMAIL
请在 devise.rb
中添加范围 email
config/devise.rb
config.omniauth :facebook, Settings.facebook.app_id, Settings.facebook.app_secret , { info_fields: 'email,first_name,last_name' , scope: 'email,public_profile' }
我想通了。谢谢!只需将 validate false 放入 user.save 以确保它保存了信息。
我在这里查找了一些问题和答案,但找不到解决我的问题的方法。我不断收到未定义的方法“持续存在?” nil:NilClass 尝试使用 Facebook 登录时。这是我的 Omniauth 回调控制器:
class OmniauthCallbacksController < ApplicationController
skip_before_filter :authenticate_user!
def provides_callback_for
user = User.from_omniauth(env["omniauth.auth"])
if user.persisted?
flash[:notice] = "You have signed in!"
sign_in_and_redirect(user)
else
session['devise.user_attributed'] = user.attributes
redirect_to new_user_registration_url
end
end
alias_method :facebook, :provides_callback_for
end
授权模型:
class Authorization < ActiveRecord::Base
belongs_to :user
after_create :fetch_details_from_facebook
def fetch_details_from_facebook
graph = Koala::Facebook::API.new(self.token)
facebook_data = graph.get_object("me")
self.username = facebook_data["username"]
self.save
end
end
和我的用户模型:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
has_many :friends
has_many :notifications
has_many :authorizations
validates_presence_of :name
validates :email, :presence => true, email_format: {message: "Please enter valid e-mail!"}
validates :phone, phone: true, presence: true
validates :birthday, :timeliness => {:on_or_before => lambda { Date.current }, :type => :date}
def self.new_with_session(params, session)
if session["devise.user_attributes"]
new(session["devise.user_attributes", without_protection: true]) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
def self.from_omniauth(auth)
authorization = Authorization.where(:provider => auth.provider, :uid => auth.uid.to_s, :token => auth.credentials.token, :secret => auth.credentials.secret).first_or_initialize
if authorization.user.blank?
user = User.where('email = ?', auth["info"]["email"]).first
if user.blank?
user = User.new
user.password = Devise.friendly_token[0, 10]
user.name = auth.info.name
user.email = auth.info.email
user.image = auth.info.image
user.save
end
authorization.username = auth.info.nickname
authorization.user_id = user.id
authorization.save
end
authorization.user
end
end
我已经尝试了很多方法,但仍然出现该错误。谁能指出我正确的方向?非常感谢非常感谢!
已更新
请确认您收到的是来自 Facebook 的电子邮件。
未经批准,Facebook 不提供 EMAIL
请在 devise.rb
email
config/devise.rb
config.omniauth :facebook, Settings.facebook.app_id, Settings.facebook.app_secret , { info_fields: 'email,first_name,last_name' , scope: 'email,public_profile' }
我想通了。谢谢!只需将 validate false 放入 user.save 以确保它保存了信息。