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
相关产品推荐
相关产品推荐

