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

升级Rails 6后Devise OmniAuth Twitter出现NoMethodError求助

问题描述

已将Rails升级至6版本,同时升级了devise。在修复CSRF错误后,出现Twitter OAuth认证失败的问题,报错信息如下:

Started POST "/users/auth/twitter" for ::1 at 2022-09-22 21:24:44 -0400
(twitter) Request phase initiated.
(twitter) Authentication failure! undefined method `downcase' for nil:NilClass

        "#{u.scheme.downcase}://#{u.host.downcase}#{(u.scheme.casecmp("http").zero? && u.port != 80) || (u.scheme.casecmp("https").zero? && u.port != 443) ? ":#{u.port}" : ""}#{u.path && u.path != "" ? u.path : "/"}"
                                        ^^^^^^^^^: NoMethodError, undefined method `downcase' for nil:NilClass

Processing by Users::OmniauthCallbacksController#failure as HTML

相关配置

Gemfile

ruby "3.1.0"
gem 'rails', '6.0.3.1'

gem 'devise'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem "omniauth-rails_csrf_protection", "~> 1.0"

登录链接(适配CSRF改为POST方法)

<%= link_to "Log In", user_twitter_omniauth_authorize_path, method: :post, "data-turbo": false %>

omniauth.rb 配置

include Devise::OmniAuth::UrlHelpers

OmniAuth.config.allowed_request_methods = [:post]
OmniAuth.config.logger = Rails.logger if Rails.env.development?

OmniAuth.config.full_host = Rails.env.production? ? 'https://www.website.com' : 'http://localhost:3000'


Rails.application.config.middleware.use OmniAuth::Builder do
    provider :facebook, ENV["FACEBOOK_KEY"], ENV["FACEBOOK_SECRET"], callback_url: ENV["FACEBOOK_CALLBACK"]

    provider :twitter, ENV['TWITTER_API_KEY'], ENV['TWITTER_API_SECRET'], {
        secure_image_url: true,
        image_size: 'original'
      }
  
    provider :apple, ENV['APPLE_CLIENT_ID'], '', {
      scope: 'email name',
      team_id: ENV['APPLE_TEAM_ID'],
      key_id: ENV['APPLE_KEY_ID'],
      pem: Base64.strict_decode64(ENV['APPLE_P8_BASE64'])
    }
end

Omniauth回调控制器

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    def self.provides_callback_for(provider)
      class_eval %Q{
        def #{provider}
          
          
          @user = User.find_for_oauth(request.env["omniauth.auth"], current_user)
          skip_authorization
          authorize @user, policy_class: OmniauthCallbackPolicy
          if @user.persisted?
            
            @user.remember_me
            sign_in_and_redirect @user, event: :authentication
            set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
          else
            
            session["devise.#{provider}_data"] = request.env["omniauth.auth"]
            redirect_to new_user_registration_url
          end
        end
      }
    end
    
    [:twitter, :facebook, :apple].each do |provider|
      provides_callback_for provider
    end
    
    def failure
      redirect_to root_path
    end
  end

routes.rb 配置

devise_for :users, defaults: { format: :html }, controllers: { omniauth_callbacks: 'users/omniauth_callbacks', passwords: 'users/passwords' }

报错代码来自oauth gem的normalized_uri方法。


解决方案

这个错误是因为OAuth请求处理回调URL时无法正确获取scheme(http/https),导致u.scheme为nil,可按以下步骤修复:

  1. 给Twitter Provider指定完整回调地址
    参照Facebook的配置,给Twitter provider添加callback_url参数,确保回调地址完整:

    provider :twitter, ENV['TWITTER_API_KEY'], ENV['TWITTER_API_SECRET'], {
        secure_image_url: true,
        image_size: 'original',
        callback_url: ENV["TWITTER_CALLBACK"] # 环境变量配置完整地址,比如http://localhost:3000/users/auth/twitter/callback
      }
    
  2. 优化OmniAuth.full_host的设置
    改用动态方式获取请求的scheme和host,避免硬编码导致的环境适配问题:

    OmniAuth.config.full_host = ->(env) {
      Rails.env.production? ? 'https://www.website.com' : "#{env['rack.url_scheme']}://#{env['HTTP_HOST']}"
    }
    
  3. 更新相关gem版本
    旧版本的omniauth-twitter和oauth gem可能存在POST请求下的URL解析bug,执行更新:

    # Gemfile中修改版本约束
    gem 'omniauth-twitter', '~> 1.4'
    gem 'oauth', '~> 0.6.0'
    

    然后运行bundle update omniauth-twitter oauth,重启服务器后测试。

  4. 确认开发环境请求Host有效性
    开发环境启动服务器时绑定0.0.0.0:rails s -b 0.0.0.0,访问时用http://0.0.0.0:3000,避免localhost解析异常导致的scheme缺失。

内容的提问来源于stack exchange,提问作者1dolinski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:40:28