我正在为我的rails应用程序编写一个自定义中间件,以解密/加密post请求中的参数。我已在'config/environments/staging.rb'
config.middleware.use CustomMiddleware
为了阅读请求参数,我正在阅读env obj,就像这样
rack_input = env['rack.input'].read
我可以访问参数并根据需要进行操作。但是当我将env
obj传递给作为接收者的app对象时。我正在
"ActionDispatch::Http::Parameters::ParseError"
完整错误
Error occurred while parsing request parameters.
Contents:
F, [2017-11-15T02:13:50.230088 #24060] FATAL -- : [9aa25c7e-56e7-4894-ba30-3a01f60ae4fc]
F, [2017-11-15T02:13:50.230340 #24060] FATAL -- : [9aa25c7e-56e7-4894-ba30-3a01f60ae4fc] ActionDispatch::Http::Parameters::ParseError (no implicit conversion of nil into String):
F, [2017-11-15T02:13:50.230563 #24060] FATAL -- : [9aa25c7e-56e7-4894-ba30-3a01f60ae4fc]
F, [2017-11-15T02:13:50.230782 #24060] FATAL -- : [9aa25c7e-56e7-4894-ba30-3a01f60ae4fc] app/middleware/custom_middleware.rb:34:in `call'
我的代码有点像这样
class CustomMiddleware
include Encryption
def initialize(app)
@app = app
end
def set_payload_params(env)
rack_input = env['rack.input'].read
@args = JSON.parse(rack_input) rescue {}
end
def call(env)
request = Rack::Request.new(env)
set_payload_params(env)
payload = @args['payload']
decrypt_params
status, headers, response = @app.call(env)
encrypt_params
end
如果我没有读取env对象并对参数进行硬编码,则没有这样的解析错误。我的控制器正在响应数据w.r.t来硬编码参数。
我的Rails版本是5.1.4 我的ruby版本是2.4.2
我在另一个rails应用程序(4.2.8)中做了类似的中间件工作正常。
对此的任何见解都会有很大帮助。提前谢谢。
答案 0 :(得分:0)
添加了一个hack,在自定义中间件中将内容类型设置为“”,这避免了在将输入转发到堆栈中的下一个组件之前对输入进行解析。
class CustomMiddleware
include Encryption
def initialize(app)
@app = app end
def set_payload_params(env)
rack_input = env['rack.input'].read
@args = JSON.parse(rack_input) rescue {} end
def call(env)
env['CONTENT_TYPE'] = ''
request = Rack::Request.new(env)
set_payload_params(env)
payload = @args['payload']
decrypt_params
status, headers, response = @app.call(env)
encrypt_params
end
答案 1 :(得分:0)
这个错误是因为在中间件(这是流)中读取后参数为空后发生的。
rack_input = env['rack.input'].read
执行此代码后,机架参数为空。现在你需要制作
env['rack.input'].rewind
或
request.body.rewind
现在您的请求又有参数了,Rails 可以简单地继续工作了。