【问题标题】:Omniauth-facebook with Devise: "Missing passthru" errors带有设计的 Omniauth-facebook:“缺少通道”错误
【发布时间】:2016-09-22 11:45:39
【问题描述】:

我安装了 Devise 身份验证,没有任何问题。现在我正在尝试添加一个使用 Omniauth-facebook 登录 Facebook 的选项。

我按照this guide 中的说明进行操作,但在访问网址localhost:3000/auth/facebook 时,我收到有关缺少“Passthru”文档的错误。

这是我得到的第一个错误:

Unknown action
The action 'passthru' could not be found for RegistrationsController

我尝试通过向我的控制器添加一个空的“passthru”操作来进行创可贴修复:

def passthru
end

这解决了这个错误,但我得到了一个不同的回报:

Template is missing
Missing template registrations/passthru, devise/registrations/passthru, devise/passthru, application/passthru with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in: * "/home/user/project/app/views" * "/home/user/.rvm/gems/ruby-2.0.0-p648@railstutorial_rails_4_0/gems/devise-3.5.2/app/views"

我尝试在所述文件夹中创建“passthru.html.erb”,但该错误仍然存​​在。无论如何,我认为这些错误象征着更深层次的问题。

还有其他人遇到过这个问题吗?我只能在上面找到this SO question,但没有一个答案有帮助。


到目前为止我的代码:

宝石文件

gem 'devise'
gem 'omniauth-facebook'
gem 'omniauth'

routes.rb

devise_for :members, controllers: { registrations: 'registrations', omniauth_callbacks: 'registrations' }

member.rb

  devise :database_authenticatable, :registerable,
         :omniauthable, :omniauth_providers => [:facebook]


  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |member|
      member.email = auth.info.email
      member.password = Devise.friendly_token[0,20]
      member.title = auth.info.name
    end
  end

registrations_controller.rb

  def facebook
    @member = Member.from_omniauth(request.env["omniauth.auth"])
    if @member.persisted?
      sign_in_and_redirect @member, :event => :authentication
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_member_registration_url
    end
  end

  def failure
    redirect_to root_path
  end

  def passthru
  end

initializers/devise.rb

config.omniauth :facebook, "<app_id>", "<app_secret>"

【问题讨论】:

  • 请描述你想通过passthru方法实现什么?
  • @PraveshKhatri 我不想用它做任何事情。该文档也没有说明任何关于 passthru 的内容。我认为这是一个旧版本的omniauth的遗物。

标签: ruby-on-rails facebook devise omniauth omniauth-facebook


【解决方案1】:

Passthru 是来自omniauth 的遗物,更新您的设计omniauth 等宝石。 有一个名为 omiauth_callback 的控制器,这是发出噪音的控制器;P.(可以帮助您追踪问题的根源)

如果你像这样在控制器中创建一个方法: def passthru end 您必须使用(甚至是空的)或重定向创建视图:从 ajax 技术中获得灵感以绕过 html 渲染。 希望它能让你走上解决问题的道路。

也试试这些路线: ``` user_omniauth_authorize /users/auth/:provider(.:format) 会话#passthru {:provider=>/facebook|twitter|google/}

user_omniauth_callback /users/auth/:action/callback(.:format) 会话#(?-mix:facebook|twitter|google) ```

【讨论】:

  • 我刚刚写了“gem 'omniauth-facebook'”,那是大约一周前的事了,所以我不应该自动拥有最新版本吗?
  • 嗯取决于 Gemfile.lock 验证这个文件,如果有必要: gem 升级 gem_name 。顺便说一句:def passthru;渲染:布局=>假;结束
  • ``` user_omniauth_authorize /users/auth/:provider(.:format) 会话#passthru {:provider=>/facebook|twitter|google/} user_omniauth_callback /users/auth/:action/callback (.:format) 会话#(?-mix:facebook|twitter|google)。 ```
【解决方案2】:

试试这个:

更新 GemFile:

gem 'omniauth-facebook'
gem 'omniauth'

转到 rails_apps/yourapp/config/initializers/devise.rb

Devise.setup do |config|
   config.omniauth :facebook, "KEY", "SECRET"
 end

更新用户模型

class User < ActiveRecord::Base

         devise :database_authenticatable, :registerable,
        :recoverable, :rememberable, :trackable, :validatable,
    :omniauthable, :omniauth_providers => [:facebook]

     def self.from_omniauth(auth)
         where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
           user.provider = auth.provider
           user.uid = auth.uid
           user.email = auth.info.email
           user.password = Devise.friendly_token[0,20]
         end
     end
    end

转到:rails_apps/yourapp/config/routes.rb

Rails.application.routes.draw do
  devise_for :users
  resources :users
end

在视图中编辑

 <%= link_to "Sign in with Facebook", "/auth/facebook", id: "sign_in" %>

【讨论】:

    【解决方案3】:

    试试这个……

    config/initializers/devise.rb

    config.omniauth :facebook, ENV["FACEBOOK_KEY"], ENV["FACEBOOK_SECRET"], { :scope => 'email, offline_access'}
    

    config/routes.rb

    devise_for :members, controllers: { registrations: 'registrations', omniauth_callbacks: "omniauth_callbacks" }
    

    app/models/member.rb

    devise :database_authenticatable, :registerable,
          :recoverable, :rememberable, :trackable, :validatable, :omniauthable
    
    
    def self.from_omniauth(auth)
      where(provider: auth.provider, uid: auth.uid).first_or_create do |member|
        member.email = auth.info.email
        member.password = Devise.friendly_token[0,20]
        member.title = auth.info.name
      end
    end 
    

    app/controllers/omniauth_callbacks_controller.rb

      skip_before_filter :authenticate_user!
    
      def facebook
        p env["omniauth.auth"]
        user = User.from_omniauth(env["omniauth.auth"])
        if user.persisted?
          flash[:notice] = "You are in..!!!"
          sign_in_and_redirect(user)
        else
          session["devise.user_attributes"] = user.attributes
          redirect_to new_user_registration_url
        end
      end
    
      def failure
        #handle you logic here..
        #and delegate to super.
        super
      end
    

    希望这对你有用。

    【讨论】:

    • 您认为我们的代码有什么不同可能导致我的错误?我找不到任何有意义的区别。
    【解决方案4】:

    您可以为Omniauth callback 创建另一个控制器

    class OmniauthCallbacksController < Devise::OmniauthCallbacksController
    
      def facebook
        @user =  User.from_omniauth(request.env['omniauth.auth'])
        if @user.persisted?
          sign_in_and_redirect @user, :event => :authentication 
          set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
        else
          session["devise.facebook_data"] = request.env["omniauth.auth"]
          redirect_to new_user_registration_url
        end
      end
    
    
      def after_sign_in_path_for(resource)
        super resource
      end
    
    end
    

    您需要将路线重置为

    devise_for :members, :controllers => {:registrations => "members/registrations", :omniauth_callbacks => 'omniauth_callbacks'}
    

    我记得你不需要在member.rb 中使用:omniauth_providers =&gt; [:facebook]

    现在您可以在 sign_up page 中添加一个按钮,或者在您的 devise/shared/_links.html.erb 中包含以下代码,因为它也可以在您的登录表单中使用。

    <%- if devise_mapping.omniauthable? %>
      <%- resource_class.omniauth_providers.each do |provider| %>
        <%= link_to "Sign up with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider), class: "btn btn-default navbar-btn" %><br />
      <% end -%>
    <% end -%>
    

    你还需要在初始化器中配置设计

    在你的/config/initializers/devise.rb

    config.omniauth :facebook, "App ID", "App Secret", scope: 'email', info_fields: 'email,name'
    

    请通过 facebook Link 阅读这个最简单的 Sing_up 教程

    【讨论】:

    • 您确定我需要单独的 Omniauth 回调控制器吗?只要路由指向正确的控制器,它所在的控制器为什么重要?
    • 是的,您可以在同一个控制器中执行此操作,但我通常在另一个控制器中执行此操作,因为这让我很清楚,如果我需要包含注册其他社交媒体,如 twitter、linkedIn 等。那么它不会在我的注册控制器中弄得一团糟。
    • 是的,所以我认为除此之外,我的代码与您发布的相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 2012-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    相关资源
    最近更新 更多