文章目录
Django——中间件、跨站伪造、auth认证
一、django请求生命周期流程图
二、django中间件
中间件是django的门户,所有的功能组件都会通过中间件校验,合格过后才能访问后端数据。只要是全局相关的功能都应该考虑使用django中间件来帮你完成。
- 全局用户身份校验
- 全局用户访问频率校验
- 用户访问黑名单等
只要用django开发业务,设计到 全局相关的功能,就会用到中间件
#中间件配置位于settings配置文件中,如果想看中间件实现过程的源码,可以将想看的某一个中间件进行模块导入,form django.middleware.security imprt SecurityMiddleware
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
django定义中间件
django支持用户自定义中间件
class SessionMiddleware(MiddlewareMixin):
def process_request(self, request):
def process_response(self, request, response):
class CsrfViewMiddleware(MiddlewareMixin):
def process_request(self, request):
def process_view(self, request, callback, callback_args, callback_kwargs):
def process_response(self, request, response):
class AuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
django运行用户自定义中间件并且暴露给用户五个可以自定义地方法
-
需要掌握的两个
#1. process_request 请求哦来的时候会按照配置文件中注册的中间件从上往下的顺序依次执行每一个中间件里面的process_request方法,如果没有直接跳过执行下一个同级别返回,并不会全部执行process_reponse #2. process_response 响应走的时候会按照配置文件中注册的中间件顺序从下往上的顺序依次执行每一个中间件里面的process_request方法,该方法必须要有两个形参,并且需要将形参response返回,如果你内部自己返回了HttpResponse对象,会将返回给用户浏览器的内容替换成你自己的
- 需要了解的三个
# 1. process_view
路由匹配成功执行视图函数之前触发
# 2. process_template_reponse
视图函数返回的对象中必须要有render属性对应的render方法
def index(request):
print('我是视图函数index')
def render():
#括号内记得不要传参数,会报错。
return HttpResponse('你好啊,我是index里面的render函数')
obj = HttpResponse('index')
obj.render = render
return obj
# 3. process_exception
当视图函数报错的时候自动触发
三、csrf跨站请求伪造
钓鱼网站
本质搭建一个跟正常网站一摸一样的页面,用户在该页面上完成转账功能,转账的请求确实是朝着正常网站的服务端提交,唯一不同的在于收款账户的不同,给用户书写form表单时,对方账户的input框没有name属性,然后在后台提前写好一个具有默认的并且是隐藏具有name属性的input框。
form表单如何让通过csrf校验
#你只需要在你的form表单内写一个
{% csrf_token %}
ajax如何通过csrf校验
// 第一种方式 自己手动获取
{#data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},#}
// 第二种方式 利用模板语法
{#data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#}
// 第三种 通用方式 引入外部js文件 官网提供的方式
{% load static %}
<script src="{% static 'myset.js' %}"></script>
data:{'username':'jason'}
csrf相关装饰器模块
当我们网站整体都校验csrf的时候,我想让某几个视图函数不校验
当我们网站整体都不校验csrf的时候,我想让某几个视图函数校验
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.views import View9
from django.utils.decorators import method_decorator
# @method_decorator(csrf_protect,name='post') # 第二种指名道姓的给类中某个方法装
# @method_decorator(csrf_exempt,name='post') # csrf_exempt 第二种方式不行
@method_decorator(csrf_exempt,name='dispatch') # 可以!!!
class MyHome(View): # APIView
# @method_decorator(csrf_protect) # 第三种 类中所有的方法都装
# @method_decorator(csrf_exempt) # csrf_exempt 第三种方式可以
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('get')
# @method_decorator(csrf_protect) # 第一种方式
# @method_decorator(csrf_exempt) # csrf_exempt 第一种方式不行
def post(self,request):
return HttpResponse('post')
"""
给CBV加装饰器 推荐你使用模块method_decorator
我们自己写的装饰器和csrf_protect用法一致
唯独csrf_exempt是一个特例 只能给dispatch方法装
"""
三、auth认证模块
django用户相关的自带的功能模块,auth_user表,
创建超级用户,数据库迁移命令行createsuperuser。
from django.contrib import auth
from django.contrib.auth.models import user
auth方法大全
-
创建用户
User.objects.create() # 密码是明文 User.objects.createuser() # 基本都用它 User.objects.createsuperuser() # 邮箱要给数据
-
校验用户名和密码是否正确
auth.authenticate(username=username,password=password) # 用户名和密码两个一个都不能少 # 该方法当用户名和密码正确的时候返回的用户对象 不正确返回None
-
保存用户登录状态
auth.login(request,user_obj) # 这一句执行之后 request.user获取当前登录的用户对象
-
如何判断当前用户是否登录,以及如何获取当前登录用户对象
request.user.is_authenticated() # 判断是否登录 request.user # 登录用户对象
-
校验用户是否登录
from django.contrib.auth.decorators import login_required # 局部配置 @login_required(login_url='/login/') def xxx(request): return HttpResponse('xxx页面') # 全局配置 配置文件中写以下代码 LOGIN_URL = '/login/' @login_required def xxx(request): return HttpResponse('xxx页面') # 如果两个都设置了 那么优先执行局部配置
-
修改密码
request.user.check_password(old_password) # 校验原密码是否正确 request.user.set_password(new_password) request.user.save() # 一定要保存
-
注销功能
auth.logout(request)
扩展auth_user表
一、利用一对一表关系() 不推荐使用
二、利用类的继承
-
类的继承
from django.contrib.auth.models import User,AbstractUser # Create your models here. class Userinfo(AbstractUser): phone = models.BigIntegerField() avatar = models.FileField() # 扩展的字段 尽量不要与原先表中的字段冲突
-
配置文件
AUTH_USER_MODEL = '应用名.表名' """ django就会将userinfo表来替换auth_user表 并且之前auth模块所有的功能不变 参照的也是userinfo表 """