欢迎转载,请支持原创,保留原文链接: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方法里面创建的。

参考

  1. Undestanding rack apps and middleware, 有对ActionDispatch, ActionPack的详解, 这是Rails的核心, 非常棒的一篇文章,值得一看。
  2. Diving in Rails - The request handling
  3. Rails 对请求的处理过程
  4. 内置middleware解释
  5. ActionDispatch middleware components
  6. Writing middleware
  7. Rails on rack, 可以通过ActionController::Dispatcher.middleware=.来替换整个middleware stack.
  8. A Deep Dive into Routing and Controller Dispatch in Rails