我开始使用omniauth和设计用户模型。整合效果很好,但案例失败了。 这是来自omniauth回调控制器的相关代码:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
before_action :find_user, only: [:facebook]
def facebook
process_omniauth_response('Facebook', request.env['omniauth.auth'], @user)
end
def failure
redirect_to root_path, flash: { error: 'Authentication \
failed, please try again!' }
end
private
def find_user
@user = User.from_omniauth(request.env['omniauth.auth'])
end
def process_omniauth_response(provider, env_data, user)
if user.persisted?
sign_in_and_redirect user, event: :authentication
set_flash_message(:notice, :success,
kind: provider) if is_navigational_format?
else
session["devise.#{provider.downcase}_data"] = env_data
redirect_to new_user_registration_url
end
end
end
用户模型方法:
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
info = auth.info
user.email = info.email
user.remote_profile_picture_url = info.image
user.name = info.name
user.password = Devise.friendly_token[0, 20]
end
end
def self.new_with_session(params, session)
super.tap do |user|
auth_data =
session['devise.facebook_data'] || session['devise.twitter_data']
fill_with_omniauth_data(user, auth_data) if auth_data
end
end
def self.fill_with_omniauth_data(user, auth_data)
data_info = auth_data['info']
user.email = data_info['email'] if user.email.blank?
user.name = data_info['name'] if user.name.blank?
...
end
所以一切正常,即如果新用户点击Facebook登录,经过Facebook认证后,他将来到预先填写数据的注册页面,但是在下面这种情况下,它将在omniauth回调后登录页面动作:
context 'when facebook email doesn\'t exist in the system' do
before(:each) do
stub_env_for_omniauth
get :facebook
end
it { response.should redirect_to new_user_registration_path }
it 'should create authentication with facebook id' do
authentication = User.where(provider: 'facebook', uid: '1234').first
puts authentication.inspect
authentication.should_not be_nil
end
end
存根方法:
def stub_env_for_omniauth
request.env['devise.mapping'] = Devise.mappings[:user]
request.env['omniauth.auth'] = OmniAuth::AuthHash.new(
provider: 'facebook', uid: '1234', info: {
email: 'ghost@nobody.com', name: 'mock user'
},
extra: { raw_info: { age: 23 } }
)
end
我收到了这条消息:
预期回复是重定向到http://test.host/users/sign_up,但重定向到http://test.host/users/sign_in
从调试开始,我得到的用户对象是新的,当我在控制器的'find_user'方法中检查它时没有持久化,但是在spec的情况下它是持久的。
我将不胜感激任何帮助。 谢谢