我使用 Google,Linkedin,Dropbox 和 Github 在设备之上设置了一个更简单的社交用户身份验证。
< em> Dropbox 身份验证不起作用,而是在回调网址上给出了该错误(http://localhost:3000/users/auth/dropbox/callback):
NoMethodError in Users::OmniauthCallbacksController#dropbox
undefined method `first' for nil:NilClass
问题:用户模型(第8行)
我的代码:
回调控制器:
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
user = User.from_omniauth(env['omniauth.auth'], current_user)
if user.persisted?
sign_in user
flash[:notice] = t('devise.omniauth_callbacks.success', :kind => User::SOCIALS[params[:action].to_sym])
if user.sign_in_count == 1
redirect_to edit_user_registration_path
else
redirect_to root_path
end
else
session['devise.user_attributes'] = user.attributes
redirect_to new_user_registration_url
end
end
User::SOCIALS.each do |k, _|
alias_method k, :all
end
end
用户模型:
# omniauth Gem
def self.from_omniauth(auth, current_user)
authorization = Authorization.where(:provider => auth.provider, :uid => auth.uid.to_s,
:token => auth.credentials.token,
:secret => auth.credentials.secret).first_or_initialize
authorization.profile_page = auth.info.urls.first.last unless authorization.persisted?
if authorization.user.blank?
user = current_user.nil? ? User.where('email = ?', auth['info']['email']).first : current_user
if user.blank?
user = User.new
user.skip_confirmation!
user.password = Devise.friendly_token[0, 20]
user.fetch_details(auth)
user.save
end
authorization.user = user
authorization.save
end
authorization.user
end
def fetch_details(auth)
self.email = auth.info.email
self.username = auth.info.name
self.avatar = URI.parse(auth.info.image)
end
我感谢每一个帮助!提前谢谢。
答案 0 :(得分:1)
直接回答您的问题:
undefined method "first" for nil::NilClass
正在发生,因为您试图在空或零对象上调用方法first
。
您可能在您的用户模型中尝试从current_user中找到用户。
if authorization.user.blank?
user = current_user.nil? ? User.where('email = ?', auth['info']['email']).first : current_user
#This will cause the error that you are describing if both the current_user is nil and there is no User whose email is auth['info']['email']
现在,这有一些问题。如果他们试图登录您的应用程序,则应该取消此阶段的current_user。
您可以尝试将其更改为
user = User.where(email: auth['info']['email']).first_or_create
如果授权中提供的电子邮件不存在,则会创建新的User实例。 然后你可以继续
user.persisted?
对于现有用户,返回true;对于User