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

Rails API only模式下Omniauth.params为空无法获取请求参数问题

问题根本原因

这是Rails API模式下的Omniauth通用问题:Omniauth作为Rack中间件运行在Rails参数解析逻辑之前,默认只能解析application/x-www-form-urlencoded和multipart/form-data格式的请求参数,JSON格式的请求体不会被自动解析到Omniauth可读取的Rack参数池中,因此会出现控制器能正常读取参数、但Omniauth拿不到参数的情况。


解决方案

1. 添加JSON请求体解析中间件

新建app/middlewares/omniauth_json_parser.rb文件,写入以下代码:

class OmniauthJsonParser
  def initialize(app)
    @app = app
  end

  def call(env)
    if env['CONTENT_TYPE'] =~ /application\/json/
      request = Rack::Request.new(env)
      body = request.body.read
      if body.present?
        params = JSON.parse(body)
        # 将解析后的参数注入到Omniauth可读取的Rack环境变量中
        env['rack.request.form_hash'] = params
        env['rack.request.form_input'] = request.body
        env['action_dispatch.request.request_parameters'] = params
      end
      request.body.rewind
    end
    @app.call(env)
  end
end

2. 注册中间件到Omniauth之前

在config/application.rb中添加中间件注册逻辑,确保参数解析在Omniauth运行前完成:

config.api_only = true
config.session_store :cookie_store, key: '_interslice_session'
config.middleware.use ActionDispatch::Cookies
config.middleware.use config.session_store, config.session_options
# 新增下面这行
config.middleware.insert_before OmniAuth::Builder, OmniauthJsonParser

3. 跳过API请求的CSRF校验

API模式下不需要CSRF校验,在你的Omniauth回调控制器中添加跳过逻辑:

module Api
  module V1
    module Auth
      class OmniauthCallbacksController < Devise::OmniauthCallbacksController
        include ActionController::Cookies
        # 新增下面这行跳过CSRF校验
        skip_before_action :verify_authenticity_token
     
        def ldap
          puts request.env['omniauth.auth']
        end

        def failure
          puts "request.env['omniauth.auth']: #{request.env['omniauth.auth']}"
          puts "request.env['omniauth.params']: #{request.env['omniauth.params']}"
          puts "params: #{params}"
          render json: { status: "fail" }
        end
      end
    end
  end
end

4. 可选兼容配置(Omniauth 2.x版本需要)

如果你后续升级到Omniauth 2.x版本,需要在config/initializers/devise.rb开头添加配置,允许POST请求发起认证:

OmniAuth.config.allowed_request_methods = [:post, :get]

验证

重启Rails服务后,发送Content-Type为application/json的POST请求,传入username和password参数即可正常触发Omniauth的LDAP认证流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:45:07