rails用middleware改environment
欢迎转载,请支持原创,保留原文链接:blog.ilibrary.me
		
		App里用到warden-jwt_auth, 这个gem在用户登录的时候需要取 env[‘HTTP_JWT_AUD’],用来生成jwt whitelist, 要不然会失败。
用middleware硬塞了一个变量进去,暂时解决这个问题。
middleware添加方法如下:
#config/application.rb
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Myapp
  class ConditionalTracker
    def initialize(app)
      @app = app
    end
    def call(env)
      env['HTTP_JWT_AUD'] = "my_jwt_aud" # 添加变量
      @app.call(env)
    end
  end
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0
    config.middleware.insert_before 1, Myapp::ConditionalTracker #  注册middleware
  end
end
可以通过rails middleware查看注册的middleware, 顶部的index为0, 刚注册的ConditionalTracker在列表的顶部.
解法二
可以在config/application.rb里给Application加一个call实例方法,改方法会overwrite Engine.call.
#config/application.rb
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Myapp
  
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0
    # Implements call according to the Rack API. It simply
    # dispatches the request to the underlying middleware stack.
    def call(env)
      env['HTTP_JWT_AUD'] = "my_jwt_aud"  # 添加变量
      super(env) # Engine.call
    end
  end
end
解法二比较简单,不加而外的middleware层。
Application在所有middleware的后面,是一个rack app, 响应call。
Middleware的创建是在rais/engine.app方法里面。
Routes是在rails/engine.routes方法里面创建的。
参考
- Undestanding rack apps and middleware, 有对ActionDispatch, ActionPack的详解, 这是Rails的核心, 非常棒的一篇文章,值得一看。
- Diving in Rails - The request handling
- Rails 对请求的处理过程
- 内置middleware解释
- ActionDispatch middleware components
- Writing middleware
- Rails on rack, 可以通过ActionController::Dispatcher.middleware=.来替换整个middleware stack.
- A Deep Dive into Routing and Controller Dispatch in Rails

