我正在尝试使用devise和omniauth实现facebook登录身份验证,但是在回调部分我遇到了错误。
错误就是这样......
> `User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."provider" = ? AND "users"."uid" = ? ORDER BY "users"."id" ASC LIMIT 1 [["provider", "facebook"], ["uid", "1517802078458724"]]
(0.1ms) begin transaction
(0.1ms) rollback transaction
Completed 500 Internal Server Error in 411ms
NameError (undefined local variable or method `user' for #<User:0x007f3008b8a760>):
app/models/user.rb:34:in `password_required?'
app/models/user.rb:18:in `block in from_omniauth'
app/models/user.rb:12:in `tap'
app/models/user.rb:12:in `from_omniauth'
app/controllers/omniauth_callbacks_controller.rb:4:in `all'`
似乎事情一直有效,直到/ auth / facebook /然后它会进入检索uid和提供者结束的部分。
我在控制器,型号和路线中的代码如下..
用于回调控制器和应用程序控制器
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
sign_in_and_redirect user, notice: "Signed in!"
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
alias_method :facebook, :all
end
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
end
我的user.rb模型
class User < ActiveRecord::Base
has_many :authentications
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :omniauthable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauth_providers => [:facebook]
attr_accessible :email, :password, :password_confirmation
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
def self.new_with_sessions(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 password_required?
super && user.blank?
end
end
我的schema.rb
ActiveRecord :: Schema.define(版本:20141120211712)做
create_table "users", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.string "provider"
t.string "uid"
t.string "name"
t.string "oauth_token"
t.datetime "oauth_expires_at"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
我的routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => { :omniauth_callbacks => "omniauth_callbacks" }
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
最后是我的gemfile
source 'https://rubygems.org'
ruby '2.1.4'
gem 'rails', '4.2.0.beta4'
gem 'bcrypt', '3.1.7'
gem 'faker', '1.4.2'
gem 'carrierwave', '0.10.0'
gem 'mini_magick', '3.8.0'
gem 'fog', '1.23.0'
gem 'will_paginate', '3.0.7'
gem 'bootstrap-will_paginate', '0.0.10'
gem 'bootstrap-sass', '3.2.0.0'
gem 'sass-rails', '5.0.0.beta1'
gem 'uglifier', '2.5.3'
gem 'coffee-rails', '4.0.1'
gem 'jquery-rails', '4.0.0.beta2'
gem 'turbolinks', '2.3.0'
gem 'jbuilder', '2.2.3'
gem 'rails-html-sanitizer', '1.0.1'
gem 'sdoc', '0.4.0', group: :doc
gem 'devise', github: 'plataformatec/devise'
gem 'omniauth'
gem 'omniauth-twitter'
gem 'omniauth-facebook'
gem 'omniauth-linkedin'
gem 'figaro'
gem 'protected_attributes'
我真的很喜欢在我的应用程序中登录facebook的这个功能...非常感谢您提前。我非常感谢任何投入..
答案 0 :(得分:1)
问题出在保存用户时调用的password_required?
。
def password_required?
super && user.blank?
end
它试图测试user
是否为空?但是,用户变量/方法在其范围内不存在。相反,您需要使用引用User的当前实例的self
。
所以该行应该是:
super && self.blank?
或只是:
super && blank?
答案 1 :(得分:0)
我能够通过制作解决这个问题
def password_required?
super && user.blank?
end
到
super && self.blank?
我还添加了
user.email = auth.info.email
到self.from_omniauth(auth)
部分。
谢谢你们