Rails 如何过滤 response 敏感词

jetspeed · 2017年09月02日 · 最后由 jetspeed 回复于 2017年09月06日 · 3188 次阅读

我有一个 rails app 通过 json 对外提供数据,有些字段得过滤成***,

比如网银里账号都显示成 123****456 这种形式。

有没有 gem 或者解决方案,可以通过一个配置,配置需要过滤的字段,对所有的对外 response 都根据配置文件过滤成***形式。

贴个代码示例:

after_action :wrap_body

def wrap_body
    if self.response.media_type == 'application/json'
      begin
        body = JSON.parse self.response.body
      rescue JSON::ParserError
        body = {}
      end
      self.response.body = { data: body }.to_json
    end
  end

通过中间件来实现,可以对所有 response 进行过滤

chalvern 回复

有现成的中间件吗?我现在想的用网关来做

这种问题上面几位为何要搞得那么复杂,这些都是属于业务的东西,与你整体实现有关系,你可以在模型层做,也可以在 view 层做,等等等 ...

@jetspeed 用网关?实在无法理解你的思维

5 楼 已删除

为何不在 Model 里面做

user.as_json(except: [:password])

http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html#method-i-as_json

然后做到 User model 里面:

class User
  def as_json(options)
    super(except: [:password, :private_token])
  end
end

https://stackoverflow.com/a/2574900

hz_qiuyuanxin 回复

需要一个整体解决方案,在模型和 view 都不太好,我目前认为在网关层好一些。同一个 api,不同的客户端,对敏感信息的需求不一致。

比如手机端需要显示成***,

pc 端不需要显示成***

jetspeed 回复

请问网关层具体是指哪个部分?谢谢

jetspeed 回复

不要瞎发明新需求

11 楼 已删除

可以参考一下 Grape::Entity

hz_qiuyuanxin 回复

我的需求就是这样啊

wwwicbd 回复

我在研究 openresty,在分发请求和 收到 response 的时候,对内容进行过滤,不知道可行不,如果 rails api 有好的解决方案也行

最明显的例子就是,现在网银,手机银行上账号都是带****的,但是同一份数据内网管理页面是不用过滤的。我想不能具体到某个实体去处理,应该在中间件或者网关,通过全局配置的敏感字段,对网银请求,手机请求,实施过滤。而后端 api 只有一份。

网关过滤等着出现莫名其妙的 bug 吧。

mobile_phone = "12345678912"
result = mobile_phone[0..2] << "****" << mobile_phone[-4..-1]
=> "123****8912"
jetspeed 回复

你想用网关过滤的主要想解决的问题是不同客户端有不同的过滤需求?

其实你只需要能够在服务端判断不同客户端就好了,用网关也是一种手段,只不过是比较复杂的一种。

jetspeed 回复

也许你代码根本不需要修改,去反馈,推动传说中的产品狗,让敏感数据全部统一即可。

如 18 楼的 @zlx_star 说的,你直接在服务器端判断是哪个端请求的,然后做相应的处理接口,在渲染之前统一对数据进行处理即可。

跟产品狗没关系,现实就是有这个需求。 我的需求是我有一个敏感字段清单,比如有 100 个,过一段时间也许增加到 200 个。所有从后端 api 出去的数据,如果到外网前端,都经过过滤,如果到内网前端,都不过滤

tinyfeng 回复

这是一个方法,但并不完全满足我上面的需求

这个可以在 nginx 里面处理 response 的 body https://github.com/openresty/replace-filter-nginx-module

w7938940 回复

这个符合我目前的需求,只是正则表达式不太好写啊,根据关键字匹配 key,替换 key 对应的 value 的一部分值。 这个项目要是有可扩展的接口就好了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号