繁体   English   中英

通过Devise / Omniauth Rails成功认证后,CallbacksController#facebook中的RuntimeError

[英]RuntimeError in CallbacksController#facebook after successful authentication with Devise / Omniauth Rails

我正在使用omniauth facebook gem设置devise以建立注册系统。 用户可以通过电子邮件注册或使用其Facebook帐户进行连接。 如果电子邮件注册用户使用facebook帐户登录,我将检查电子邮件地址是否已注册并连接这两个帐户,然后登录该用户。

这整个方案已经起作用。 用新的facebook omniauth数据更新用户条目。 当facebook发送回调(从facebook的数据成功保存到db)时,出现此错误:

CallbacksController#facebook中的RuntimeError

找不到有效的映射,该映射为true

提取的源(第5行附近):

class CallbacksController < Devise::OmniauthCallbacksController
  # Define each provider for omniauth here (def twitter...)
  def facebook
    @user = User.from_omniauth(request.env["omniauth.auth"])
    sign_in_and_redirect @user
  end
end

user.rb modell看起来像这样:

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, :omniauth_providers => [:facebook]

  def self.from_omniauth(auth)
    user = where(provider: auth.provider, uid: auth.uid).first
    unless user
      user = where(email: auth.info.email).first_or_initialize
      user.provider = auth.provider
      user.uid = auth.uid
      user.email = auth.info.email
      user.name = auth.info.name
      user.nickname = auth.info.nickname
      user.first_name = auth.info.first_name
      user.last_name = auth.info.last_name
      user.location = auth.info.location
      user.description = auth.info.description
      user.image = auth.info.image
      user.phone = auth.info.phone
      user.urls = auth.info.urls
      user.password = Devise.friendly_token[0,20]
      user.save!
    end
  end
end

routes.rb

Rails.application.routes.draw do
  devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" }
  resources :auctions do
    resources :comments
  end

  root 'welcome#index'
  get '/', :to => 'welcome#index'
end

您的User类中的self.from_omniauth方法返回true ,而不是User模型。 这是因为Ruby中方法的返回值是最后一行求值的结果 ,在本例中为user.save! 是最后一行。 错误“找不到为true的有效映射”是将true传递给sign_in_and_redirect的结果; 您可以在Devise源代码中看到第一个参数已传递到Devise::Mapping.find_scope!

解决方案很简单-确保在from_omniauth返回user模型:

def self.from_omniauth(auth)
    user = where(provider: auth.provider, uid: auth.uid).first
    unless user
      user = where(email: auth.info.email).first_or_initialize
      user.provider = auth.provider
      user.uid = auth.uid
      user.email = auth.info.email
      user.name = auth.info.name
      user.nickname = auth.info.nickname
      user.first_name = auth.info.first_name
      user.last_name = auth.info.last_name
      user.location = auth.info.location
      user.description = auth.info.description
      user.image = auth.info.image
      user.phone = auth.info.phone
      user.urls = auth.info.urls
      user.password = Devise.friendly_token[0,20]
      user.save!
    end
    user # Make sure we return the user we constructed.
  end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM