django 实现审计中心中间件
需求描述
起一个中间件将所有的请求拦截进行校验的同时记录相关的访问信息
主要用于审计职能, 需记录用户信息, 访问资源, 访问方式以及请求结果等
需求实现
主要结合中间件的 process_request 和 process_response 来实现
请求的信息记录主要由以下内置便利来截取
request.path 请求url request.user 请求用户 request.META['REMOTE_ADDR'] 请求终端IP request.GET GET请求参数 request.body POST请求参数 response.status_code 响应状态码 response.reason_phrase 响应结果
问题处理
其中会遇到一些问题如
'WSGIRequest' object has no attribute 'data'
在视图中可以通过 request.data 直接调取 POST 请求的参数信息. 但是在中间件中是不可行的
还有这个问题
You cannot access body after reading from request‘s data stream
问题较为复杂,大体意思是不允许直接使用
但是解决方式也较为简单, 通过复制一个新的变量即可
re_request_body = getattr(request,'_body',request.body) print(re_request_body)
注意: 此方法只适用于在 process_request 中
解决方式如下, 中间件内同一个作用域下的数据是互通的, 写入传递记录即可
详细代码实现
class AuditMiddleware(MiddlewareMixin): re_request_body = None
def process_request(self, request): self.re_request_body = None if request.method != "GET": body_content = getattr(request, '_body', request.body) self.re_request_body = eval(body_content.decode("utf-8")) print(self.re_request_body)
def audit_record(self, request, response): re_request_body = self.re_request_body Audit.objects.create( path=request.path, request_method=request.method, user=request.user, parameter=request.GET if request.method == "GET" else re_request_body, ip_addr=request.META['REMOTE_ADDR'], status_code=response.status_code, reason_phrase=response.reason_phrase, ) self.re_request_body = None return
暂不清楚中间件的每次请求都会实例化还是会单例, 如果单例的话考虑会出现后面是post 请求覆盖不到前面的情况
所以保险起见每次用完就清空中间变量最好
本文来自博客园,作者:羊驼之歌,转载请注明原文链接:https://www.cnblogs.com/shijieli/p/16457775.html