一、基于配置文件的编程思想

反射

通过字符串操作类和函数

1. importlib 模块

importlib模块可以通过字符串取出其对应的模块。

  1. import importlib
  2. res = 'lib.bbb'
  3. # 利用字符串的形式导入模块
  4. md = importlib.import_module(res)
  5. # from lib import bbb md相当于bbb
  6. print(md) # 该模块字符串最小单位只能到文件名

2. 配置文件

当我们导入一个模块的时候,我们其实是在导入这个模块文件夹中的__init__.py文件。

该文件中可以导入配置文件中的配置信息。

我们在配置文件中提前将导入其他模块的具体路径写成字符串的形式,保存成配置信息。

然后在__init__.py文件中通过importlib模块将导入的配置文件的中的配置信息字符串解析成真正的模块路径进行导入。

这样我们就可以在配置文件中输入字符串来进行模块的导入啦!而且如果我们有一些模块及功能不需要用到时,我们直接将配置文件中的路径字符串注释掉就行了。

二、跨站请求伪造(csrf)

1.csrf简介以及由来

Cross—Site Request Forgery:跨站请求伪造

有些钓鱼网站会写成与正规网站一样的界面,诱导用户使用并提交数据。当钓鱼网站接收到用户本来想发送到正规网站的数据后,钓鱼网站将这组信息进行一些修改,将其关键信息改成自己想要的数据,再把这组修改后的网站发送给正规网站进行处理。

这样钓鱼网站就达到了窃取用户信息并从中牟利的目的。这样就会使得用户与正规网站遭受损失。

为了防止这样的情况,正规网站对接受的数据做了一些处理。规定本网站只会处理自己本页面提交的post请求。

这样就可以保证从钓鱼网站发过来的跨站请求失效。

而csrf就是用来进行这样的操作的中间件。通过这个中间件,后端在向前端发送HTML页面时,会在form表单里添加一个具有name属性的input框,并且value是用户登录的真实账户,然后将这个标签隐藏。

这样用户在提交数据时,后端就可以校验你是否有这个隐藏标签,如果有,就说明你是真实用户。如果没有,就说明是其他网站发送的伪造请求。

这样就可以做到保证用户权益的目的了。

2.Django中的csrf中间件如何使用

csrf中间件在配置文件中已经写好,如果不将该中间件注释,它会自动帮后端朝前端发送HTML文件时,加入csrf_token。

这时前端再想向后端发送数据,就必须要携带csrf_token校验参数,使前端数据通过后端的csrf校验。

2.1 普通form表单提交数据

前端如何携带csrf_token:

  1. {# 你只需要在表单中写一个{% csrf_token %} #}
  2. <form action="" method="post">
  3. {% csrf_token %}
  4. {# csrf_token必须写在form表单里面 #}
  5. <p>username:<input type="text" name="username"></p>
  6. <p>target_account:<input type="text" name="target_user"></p>
  7. <p>money:<input type="text" name="money"></p>
  8. <input type="submit">
  9. </form>

2.2 ajax提交数据

方式1:较为繁琐

先在页面任意的位置上书写{% csrf_token %};

然后在发送ajax请求的时候通过标签查找获取随机字符串,添加到data自定义对象即可。

  1. <script>
  2. $('#d1').click(function () {
  3. $.ajax({
  4. url:'',
  5. type:'post',
  6. // 第一种
  7. data:{
  8. 'username':'jason',
  9. 'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()
  10. },
  11. success:function (data) {
  12. alert(data)
  13. }
  14. })
  15. })
  16. </script>

方式2:较为简单

  1. <script>
  2. $('#d1').click(function () {
  3. $.ajax({
  4. url:'',
  5. type:'post',
  6. // 第二种
  7. data:{
  8. 'username':'jason',
  9. 'csrfmiddlewaretoken':'{{ csrf_token }}' {# 要加一下引号 #}
  10. }, {# 要加一下引号 #}
  11. success:function (data) {
  12. alert(data)
  13. }
  14. })
  15. })
  16. </script>

方式3:官网提供文件(最通用的一种方式)

直接新建js文件拷贝代码,导入即可;

你不需要做任何的csrf相关的代码书写

你不需要做任何的csrf相关的代码书写

  1. <script src="/static/setup.js"></script>
  2. <script>
  3. $('#d1').click(function () {
  4. $.ajax({
  5. url:'',
  6. type:'post',
  7. // 第三种 利用脚本文件 啥也不用写
  8. data:{'username':'jason'},
  9. success:function (data) {
  10. alert(data)
  11. }
  12. })
  13. })
  14. </script>

3.csrf相关的装饰器

3.1 csrf_exempt

如果中间件设置了需要全局校验csrf,那么该装饰器可以让函数不进行校验。

  1. # @csrf_exempt # 不校验 csrf
  2. def index(request):
  3. return HttpResponse('index') # 不需要也可以交互

3.2 csrf_protect

如果csrf中间件被注释掉了,设置了全局不校验csrf,那么该函数可以

  1. @csrf_protect # 校验
  2. def login(request):
  3. return HttpResponse('login')

3.3 如何在CBV的函数中使用上面两个函数

  1. csrf_exempt这个装饰器只能给dispatch装才能生效;
  2. csrf_protect任何方式都可以,和普通的装饰器装饰CBV一致。
  1. # @method_decorator(csrf_exempt,name='post') # csrf_exempt不支持该方法
  2. @method_decorator(csrf_exempt,name='dispatch') # 可以
  3. class MyIndex(views.View):
  4. # @method_decorator(csrf_exempt) # 可以
  5. def dispatch(self, request, *args, **kwargs):
  6. return super().dispatch(request,*args,**kwargs)
  7. def get(self,request):
  8. return render(request,'transfer.html')
  9. # @method_decorator(csrf_exempt,name='post') # csrf_exempt不支持该方法
  10. def post(self,request):
  11. return HttpResponse('OK')
  12. # @method_decorator(csrf_protect,name='post') # 可以
  13. class MyIndex(views.View):
  14. @method_decorator(csrf_protect) # 可以
  15. def dispatch(self, request, *args, **kwargs):
  16. return super().dispatch(request,*args,**kwargs)
  17. def get(self,request):
  18. return render(request,'transfer.html')
  19. # @method_decorator(csrf_protect) # 可以
  20. def post(self,request):
  21. return HttpResponse('OK')

三、Django auth管理

Auth模块是Django自带的用户认证模块。

有django帮我们做登录认证,很多东西都不用自己写了,真的很开心呢!

用户数据会储存在数据迁移时,Django自动帮我们创建的auth_user表中。

1. auth模块常用方法

1.1 创建用户

想要使用auth创建用户需要先从django.contrib.auth.models导入user模块:

  1. from django.contrib.auth.models import User
  2. # 不可用 密码不是加密的
  3. # User.objects.create(username=username,password=password)
  4. # 创建普通用户 密码自动加密
  5. User.objects.create_user(username=username,password=password)
  6. # 创建超级用户 需要邮箱数据 密码自动加密
  7. User.objects.create_superuser(username=username,password=password,email='123@qq.com')
  8. # 源码
  9. def create_user(self, username, email=None, password=None, **extra_fields):
  10. extra_fields.setdefault('is_staff', False)
  11. extra_fields.setdefault('is_superuser', False)
  12. return self._create_user(username, email, password, **extra_fields)
  13. def create_superuser(self, username, email, password, **extra_fields):
  14. extra_fields.setdefault('is_staff', True)
  15. extra_fields.setdefault('is_superuser', True)

1.2 校验用户名和密码

想要使用auth校验用户名和密码需要先从django.contrib导入auth模块:

  1. from django.contrib import auth
  2. user_obj = auth.authenticate(request,username=username,password=password)
  3. # 必须传用户名和密码两个参数 缺一不可

如果该用户未找到则user_obj返回none。

1.3 保存用户登录状态

使用auth.login(request,user_obj)保存用户登录状态,自动在user_session表中记录。

  1. def login(request):
  2. if request.method == 'POST':
  3. username = request.POST.get('username')
  4. password = request.POST.get('password')
  5. user_obj = auth.authenticate(request,username=username,password=password)
  6. # print(user_obj)
  7. if user_obj:
  8. # print(user_obj)
  9. # print(type(user_obj))
  10. # 保存用户登录状态,在session表中保存用户
  11. # 相当于request.session['user'] = 'name'
  12. # 且只要执行了这一句话,
  13. # 之后你可以在任意位置通过request.user获取到当前登录用户对象
  14. auth.login(request,user_obj)
  15. return HttpResponse('登陆成功!')
  16. return render(request,'login.html')

1.4 判断当前用户是否登录

使用request.user.is_authenticated()判断用户是否登录,返回布尔值,True/False。

  1. def check_login(request):
  2. if request.user.is_authenticated():
  3. return HttpResponse('login')
  4. else:
  5. return HttpResponse('not login')

1.5 校验原密码是否正确

通过request.user.check_password(旧密码)来校验用户是否输入了正确的密码,返回值为布尔值True/False。

  1. @login_required # 局部登录跳转页面配置
  2. def check_password(request):
  3. user_obj = request.user # 获取已经登陆的用户
  4. if request.method == 'POST':
  5. old_password = request.POST.get('old_password')
  6. new_password = request.POST.get('new_password')
  7. # 校验原来的密码是否正确 返回布尔
  8. is_right = user_obj.check_password(old_password)
  9. if is_right:
  10. user_obj.set_password(new_password)
  11. user_obj.save()
  12. return HttpResponse('修改成功!')
  13. return render(request,'change_password.html')

1.6 修改密码

通过request.user.set_password(新密码)来修改用户的密码,修改完成后需要执行request.user.save()来将修改后的数据写入数据库。

不然数据只是在缓存中修改了一下,没有真正写入数据库。

  1. @login_required # 局部登录跳转页面配置
  2. def check_password(request):
  3. user_obj = request.user # 获取已经登陆的用户
  4. if request.method == 'POST':
  5. old_password = request.POST.get('old_password')
  6. new_password = request.POST.get('new_password')
  7. # 校验原来的密码是否正确 返回布尔
  8. is_right = user_obj.check_password(old_password)
  9. if is_right:
  10. # 修改用户密码,并保存
  11. user_obj.set_password(new_password)
  12. user_obj.save()
  13. return HttpResponse('修改成功!')
  14. return render(request,'change_password.html')

1.7 注销

直接通过auth.logout(request)方法注销用户。

  1. @login_required
  2. def logout(request):
  3. auth.logout(request)
  4. return HttpResponse('用户已注销!')

1.8 校验用户是否登录装饰器

1.首先需要导入登录认证装饰器模块函数

  1. from django.contrib.auth.decorators import login_required

2.然后可以设置未登录时跳转到登录页面的url

局部配置

  1. @login_required(login_url='/login/')
  2. def func(request):
  3. pass

全局配置 (settings配置文件中 直接配置)

  1. # settings中配置
  2. LOGIN_URL = '/login/'
  3. # views
  4. @login_required
  5. def func(request):
  6. pass

注意:

如果全局配置了,局部也配置,将以局部的login_url为准。

2. 扩展auth_user表中的字段

2.1 利用一对一建立外键关系表

另写一张表用来存放需要添加的字段,用一对一的关系外键绑定到auth_user表上。

绑定之前需要把from django.contrib.auth.models import User自动创建的表导过来。

  1. # models
  2. from django.contrib.auth.models import User
  3. class UserDetail(models.Model):
  4. phone = models.BigIntegerField()
  5. user = models.OneToOneField(to='User')

2.2 继承Django提供的auth类

在创建所有表之前直接修改本应该有的auth_user表。

通过继承User表的父类,自己重写新的User类。

继承之前同样需要将User父类from django.contrib.auth.models import AbstractUser导过来。

  1. # models
  2. from django.contrib.auth.models import AbstractUser
  3. class Userinfo(AbstractUser):
  4. phone = models.BigIntegerField()
  5. register_time = models.DateField(auto_now_add=True)

注意:

自己重写类后,需要在配置文件中配置一下,不然系统不知道你要自己重写表了。

写完之后,之前所有的auth模块功能也全都可以通过你新写的表使用。

  1. # settings
  2. AUTH_USER_MODEL = 'app01.Userinfo' # 应用名.表名

Django之csrf中间件及auth模块使用的更多相关文章

  1. Django框架之中间件与Auth

    Django框架之中间件与Auth模块一 cbv加装饰器 -先导入:from django.utils.decorators import method_decorator -1 可以在方法上加装饰器 ...

  2. Django 中CSRF中间件 'django.middleware.csrf.CsrfViewMiddleware',

    1.Django中CSRF中间件的工作原理及form表单提交需要添加{% csrf_token %}防止出现403错误 CSRF # 表示django全局发送post请求均需要字符串验证功能:防止跨站 ...

  3. django中间件和auth模块

    Django中间件 由django的生命周期图我们可以看出,django的中间件就类似于django的保安,请求一个相应时要先通过中间件才能到达django后端(url.views.template. ...

  4. Django CBV加装饰器、Django中间件、auth模块

    一. CBV加装饰器 在视图层中,基于函数的视图叫FBV(function base views),基于类的视图叫CBV(class base views).当需要用到装饰器时,例如之前的基于Cook ...

  5. 中间件和auth模块

    中间件 1.什么是中间件 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用 ...

  6. Django 自带认证功能auth模块和User对象的基本操作

    一.auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: authenticate()    ...

  7. Django的csrf中间件

    csrf中间件 ​ csrf 跨站请求伪造 ​ 补充两个装饰器: ​ from django.views.decorators.csrf import csrf_exempt,csrf_protect ...

  8. python框架之Django(12)-认证系统之auth模块

    我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Django作为一个完美主义者的终极框 ...

  9. Django 认证系统 cookie & session & auth模块

    概念 cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生. cookie的工作原理是:由服务器产生内容,浏 ...

随机推荐

  1. Docker容器管理平台Rancher高可用部署——看这篇就够了

    记得刚接触Rancher时,看了官方文档云里雾里,跟着官网文档部署了高可用Rancher,发现不管怎么折腾都无法部署成功(相信已尝试的朋友也有类似的感觉),今天腾出空来写个总结,给看到的朋友留个参考( ...

  2. 图的连通性——Tarjan算法&割边&割点

    tarjan算法 原理: 我们考虑 DFS 搜索树与强连通分量之间的关系. 如果结点 是某个强连通分量在搜索树中遇到的第⼀个结点,那么这个强连通分量的其余结点肯定 是在搜索树中以 为根的⼦树中. 被称 ...

  3. codeforces 292E. Copying Data

    We often have to copy large volumes of information. Such operation can take up many computer resourc ...

  4. 牛客编程巅峰赛S2第10场 - 钻石&王者 C.牛牛的路径和 (位运算,dfs)

    题意:给你节点数为\(n\)的树,每个节点都有自己的权值,求所有路径的上的点的权值按位与的和. 题解:题目给的数据很大,我们不能直接去找.因此我们可以枚举二进制\([1,20]\)的每一位,然后再枚举 ...

  5. Codeforces Round #594 (Div. 2) C. Ivan the Fool and the Probability Theory (思维,递推)

    题意:给你一个\(n\)x\(m\)的矩阵,需要在这些矩阵中涂色,每个格子可以涂成黑色或者白色,一个格子四周最多只能有\(2\)个和它颜色相同的,问最多有多少种涂色方案. 题解:首先我们考虑一维的情况 ...

  6. 2018-2019 ACM-ICPC, Asia Dhaka Regional Contest C.Divisors of the Divisors of An Integer (数论)

    题意:求\(n!\)的每个因子的因子数. 题解:我们可以对\(n!\)进行质因数分解,这里可以直接用推论快速求出:https://5ab-juruo.blog.luogu.org/solution-p ...

  7. 在kubernetes集群里集成Apollo配置中心(5)之dubbo服务消费者连接apollo实战

    1.在Apollo的portal创建dubbo消费者项目 (1)添加dubbo消费者项目 (2)在dubbo消费者项目中添加配置项 (3)发布 2.通过jenkins构建dubbo消费者镜像 3.登录 ...

  8. kubernetes实战-配置中心(二)交付apollo配置中心到k8s

    apollo官网:官方地址 apollo架构图: apollo需要使用数据库,这里使用mysql,注意版本需要在5.6以上: 本次环境mysql部署在10.4.7.11上,使用mariadb:10.1 ...

  9. DOCKER - 构建一个docker镜像并跑起来

    一.有个基础镜像 1.基础镜像的选择 当前市场有众多可选择的基础docker镜像,可参考: https://blog.csdn.net/nklinsirui/article/details/80967 ...

  10. synchronized底层原理

    synchronized底层语义原理 Java 虚拟机中的同步(Synchronization)基于进入和退出管程(Monitor)对象实现. 在 Java 语言中,同步用的最多的地方可能是被 syn ...