You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中Devise-Omniauth路由指向passthru而非Twitter的问题排查

Devise集成omniauth-twitter出现"Not found. Authentication passthru"错误排查

问题现象

尝试在Ruby on Rails中通过Devise集成omniauth-twitter,按照官方文档使用POST请求的授权链接:

<%= link_to "Sign up with twitter", user_twitter_omniauth_authorize_path,
    method: :post %>

已通过Turbo.session.drive = false全局禁用Turbo,但点击链接后页面显示:

Not found. Authentication passthru.

查看路由发现异常:

% bin/rails routes -g omni
                          Prefix Verb     URI Pattern                             Controller#Action
user_twitter_omniauth_authorize GET|POST /users/auth/twitter(.:format)          users/omniauth_callbacks#passthru
 user_twitter_omniauth_callback GET|POST /users/auth/twitter/callback(.:format) users/omniauth_callbacks#twitter

授权路由指向不存在的Users::OmniauthCallbacksController#passthru方法,且已通过日志确认使用POST请求,排除请求方法和Turbo影响。

已确认的前提条件

  • 使用Twitter OA1 API密钥(OA2暂不被Omniauth支持)
  • 已在Twitter开发者中心启用"User authentication set up",允许用户登录

相关配置文件

Gemfile

# Gemfile
gem 'devise'
gem 'devise-i18n'
gem 'omniauth', '~> 2.1'
gem 'omniauth-twitter'
gem 'omniauth-rails_csrf_protection', '~> 1.0'

注:已将omniauth-rails_csrf_protection从0.1.2升级到1.0.1,问题仍存在

config/initializers/devise.rb

# /config/initializers/devise.rb
Devise.setup do |config|
  config.omniauth :twitter, 'MY_APP', 'MY_SECRET'
  OmniAuth.config.logger = Rails.logger if Rails.env.development? # 调试用
end

注:config/initializers/目录下无其他Omniauth或Twitter相关配置文件

app/models/user.rb

# /models/user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable, # 省略其他配置
         :omniauthable, omniauth_providers: %i(twitter)

  def self.from_omniauth(auth)
    find_or_create_by(provider: auth.provider, uid: auth.uid) do |user|
      user.display_name = auth.info.nickname.strip
      user.skip_confirmation!
    end
  end
end

app/controllers/users/omniauth_callbacks_controller.rb

# /app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  skip_before_action :verify_authenticity_token, only: [:twitter]

  def twitter
    callback_from __method__
  end

  def callback_from(provider)
    @user = User.from_omniauth(request.env['omniauth.auth'])

    if @user.persisted?
      sign_in_and_redirect @user, event: :authentication
      set_flash_message(:notice, :success, kind: provider.to_s.capitalize) if is_navigational_format?
    else
      session["devise.#{provider.to_s}_data"] = request.env['omniauth.auth'].except(:extra)
      redirect_to new_user_registration_url(from_omniauth_callback: true)
    end
  end

  def failure
    redirect_to root_path
  end
end

config/routes.rb

# /config/routes.rb
Rails.application.routes.draw do
  devise_for :users, except: [:destroy], 
    controllers: { omniauth_callbacks: 'users/omniauth_callbacks' } 
end

视图文件

<%# /app/views/devise/registrations/new.html.erb %>
<%= link_to t(".sign_up_with_twitter"), user_twitter_omniauth_authorize_path,
  method: :post, data: { turbo: false } %>

服务器日志

00:... | I, [2022-...6 #793]  INFO -- : Started POST "/en/users/auth/twitter" for 127.0.0.1 at 2022-11-27 00:33:14 +0000
00:... | I, [2022-...4 #793]  INFO -- : Processing by Users::OmniauthCallbacksController#passthru as HTML
00:... | I, [2022-...0 #793]  INFO -- :   Parameters: {"authenticity_token"=>"[FILTERED]", "locale"=>"en"}
00:... | D, [2022-...0 #793] DEBUG -- :   Rendering text template
00:... | I, [2022-...7 #793]  INFO -- :   Rendered text template (Duration: 0.0ms | Allocations: 10)
00:... | I, [2022-...9 #793]  INFO -- : Completed 404 Not Found in 4ms (Views: 2.5ms | ActiveRecord: 0.0ms | Allocations: 1170)

版本信息

  • omniauth-rails_csrf_protection (1.0.1)
  • omniauth (2.1.0)
  • omniauth-oauth (1.2.0)
  • omniauth-twitter (1.4.0)
  • devise (4.8.1)
  • rails (7.0.4)
  • ruby (3.1.2)

可能的原因及解决方法

1. Omniauth策略未正确加载

passthru是Devise在找不到对应Omniauth策略时的 fallback 动作,说明Rails未正确加载omniauth-twitter策略。

  • 执行bundle install后重启服务器,确保omniauth-twitter gem已正确安装
  • 确认config/initializers/devise.rb中config.omniauth :twitter, 'MY_APP', 'MY_SECRET'的API密钥和密钥为真实有效内容
  • 尝试在config/application.rb中添加require 'omniauth-twitter',强制加载策略

2. Omniauth 2.x CSRF保护配置冲突

Omniauth 2.x对CSRF保护要求更严格,可能存在配置冲突:

  • 移除控制器中的skip_before_action :verify_authenticity_token, only: [:twitter],omniauth-rails_csrf_protection会自动处理回调的CSRF验证
  • 确认视图中link_to的method: :post正确生成POST请求,而非默认GET

3. Devise与Omniauth路由映射异常

路由指向passthru说明Devise未正确映射授权路径到Omniauth逻辑:

  • 检查User模型中devise ... :omniauthable, omniauth_providers: %i(twitter)配置完整,确保:omniauthable和omniauth_providers已添加
  • 执行rails generate devise:omniauth_callbacks User重新生成回调控制器,对比现有控制器的差异
  • 确认routes.rb中devise_for :users的控制器映射正确

4. Twitter开发者配置缺失

尽管已启用用户认证,仍可能存在配置遗漏:

  • 在Twitter开发者中心,确认应用的"Callback URL"设置为开发环境的http://localhost:3000/users/auth/twitter/callback(生产环境替换为真实域名)
  • 确认应用的"App permissions"至少设置为"Read"权限
  • 再次核对API密钥和密钥,确保无多余空格或字符

内容的提问来源于stack exchange,提问作者Masa Sakano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 01:15:54