class MiddlewareMixin:
#django启动时就执行,与用户无关
def __init__(self, get_response=None):
self.get_response = get_response
super().__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
#request到达views之前执行,如果在process_request函数中有返回值一般就会直接返回的不会执行以后的中间件
response = response or self.get_response(request)
#后面的中间件和views执行完成后返回
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
例子:csrf_token:csrf原理:https://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
推荐一篇关与csrf中间件的文章 https://blog.csdn.net/qq_27952549/article/details/82392790
CSRF攻击的过程
1.用户C浏览并登陆信任的站点A
2.A验证通过,在用户C处产生A的Cookie
3.用户C在没有登陆的情况下访问攻击站点B
4.B要求访问第三方的站点A,发出一个请求
5.根据B在4的请求,浏览器携带2产生的cookie访问站点A
6.A不知道5中的请求是用户C发出的还是B发出的,由于浏览器会自动带上用户C的Cookie,所以A会个根据C的权限处理5的请求,这样B就达到了模拟用户登录的目的
如何防止CSRF的攻击?
1.在客户端向后端请求界面数据的时候,后端会往响应中的cookie中设置csrf_token的值
2.在Form表单中添加一个隐藏字段,值也是csrf_token
3.在用户提交的时候,会带上这两个值向后台发起请求
4.后端接收到请求以后,会做三件事:
从cookie中取出csrf_token
从表单数据中取出隐藏的csrf_token的值
将这两个值进行比对
5.如果比较后两个值一样,那么代表是正常的请求,如果没有取到或者比较不一致,代表不是正常的请求,不执行下一步操作
总结:就是说你虽然替他登录了,但是以后的访问还必须需要你的token才能进行一些修改数据的操作,不然还是不能执行。
token值更新速度快,值保存在前端,cookie中和要提交表单中,然后后端进行比较这两值。
生成cookie
def get_token(request):
"""
Return the CSRF token required for a POST form. The token is an
alphanumeric value. A new token is created if one is not already set.
A side effect of calling this function is to make the csrf_protect
decorator and the CsrfViewMiddleware add a CSRF cookie and a 'Vary: Cookie'
header to the outgoing response. For this reason, you may need to use this
function lazily, as is done by the csrf context processor.
"""
#如果request.META中没有CSRF_COOKIE,就会给添加一个CSRF_COOKIE字段
if "CSRF_COOKIE" not in request.META:
csrf_secret = _get_new_csrf_string()
request.META["CSRF_COOKIE"] = _salt_cipher_secret(csrf_secret)
else:
#如果有CSRF_COOKIE就解密
csrf_secret = _unsalt_cipher_token(request.META["CSRF_COOKIE"])
request.META["CSRF_COOKIE_USED"] = True
return _salt