Django之csrf中间件及auth模块使用
一、基于配置文件的编程思想
反射
通过字符串操作类和函数
1. importlib 模块
importlib模块可以通过字符串取出其对应的模块。
import importlib
res = 'lib.bbb'
# 利用字符串的形式导入模块
md = importlib.import_module(res)
# from lib import bbb md相当于bbb
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:
{# 你只需要在表单中写一个{% csrf_token %} #}
<form action="" method="post">
{% csrf_token %}
{# csrf_token必须写在form表单里面 #}
<p>username:<input type="text" name="username"></p>
<p>target_account:<input type="text" name="target_user"></p>
<p>money:<input type="text" name="money"></p>
<input type="submit">
</form>
2.2 ajax提交数据
方式1:较为繁琐
先在页面任意的位置上书写{% csrf_token %};
然后在发送ajax请求的时候通过标签查找获取随机字符串,添加到data自定义对象即可。
<script>
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
// 第一种
data:{
'username':'jason',
'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()
},
success:function (data) {
alert(data)
}
})
})
</script>
方式2:较为简单
<script>
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
// 第二种
data:{
'username':'jason',
'csrfmiddlewaretoken':'{{ csrf_token }}' {# 要加一下引号 #}
}, {# 要加一下引号 #}
success:function (data) {
alert(data)
}
})
})
</script>
方式3:官网提供文件(最通用的一种方式)
直接新建js文件拷贝代码,导入即可;
你不需要做任何的csrf相关的代码书写
你不需要做任何的csrf相关的代码书写
<script src="/static/setup.js"></script>
<script>
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
// 第三种 利用脚本文件 啥也不用写
data:{'username':'jason'},
success:function (data) {
alert(data)
}
})
})
</script>
3.csrf相关的装饰器
3.1 csrf_exempt
如果中间件设置了需要全局校验csrf,那么该装饰器可以让函数不进行校验。
# @csrf_exempt # 不校验 csrf
def index(request):
return HttpResponse('index') # 不需要也可以交互
3.2 csrf_protect
如果csrf中间件被注释掉了,设置了全局不校验csrf,那么该函数可以
@csrf_protect # 校验
def login(request):
return HttpResponse('login')
3.3 如何在CBV的函数中使用上面两个函数
- csrf_exempt这个装饰器只能给dispatch装才能生效;
- csrf_protect任何方式都可以,和普通的装饰器装饰CBV一致。
# @method_decorator(csrf_exempt,name='post') # csrf_exempt不支持该方法
@method_decorator(csrf_exempt,name='dispatch') # 可以
class MyIndex(views.View):
# @method_decorator(csrf_exempt) # 可以
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return render(request,'transfer.html')
# @method_decorator(csrf_exempt,name='post') # csrf_exempt不支持该方法
def post(self,request):
return HttpResponse('OK')
# @method_decorator(csrf_protect,name='post') # 可以
class MyIndex(views.View):
@method_decorator(csrf_protect) # 可以
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return render(request,'transfer.html')
# @method_decorator(csrf_protect) # 可以
def post(self,request):
return HttpResponse('OK')
三、Django auth管理
Auth模块是Django自带的用户认证模块。
有django帮我们做登录认证,很多东西都不用自己写了,真的很开心呢!
用户数据会储存在数据迁移时,Django自动帮我们创建的auth_user表中。
1. auth模块常用方法
1.1 创建用户
想要使用auth创建用户需要先从django.contrib.auth.models导入user模块:
from django.contrib.auth.models import User
# 不可用 密码不是加密的
# User.objects.create(username=username,password=password)
# 创建普通用户 密码自动加密
User.objects.create_user(username=username,password=password)
# 创建超级用户 需要邮箱数据 密码自动加密
User.objects.create_superuser(username=username,password=password,email='123@qq.com')
# 源码
def create_user(self, username, email=None, password=None, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(username, email, password, **extra_fields)
def create_superuser(self, username, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
1.2 校验用户名和密码
想要使用auth校验用户名和密码需要先从django.contrib导入auth模块:
from django.contrib import auth
user_obj = auth.authenticate(request,username=username,password=password)
# 必须传用户名和密码两个参数 缺一不可
如果该用户未找到则user_obj返回none。
1.3 保存用户登录状态
使用auth.login(request,user_obj)保存用户登录状态,自动在user_session表中记录。
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user_obj = auth.authenticate(request,username=username,password=password)
# print(user_obj)
if user_obj:
# print(user_obj)
# print(type(user_obj))
# 保存用户登录状态,在session表中保存用户
# 相当于request.session['user'] = 'name'
# 且只要执行了这一句话,
# 之后你可以在任意位置通过request.user获取到当前登录用户对象
auth.login(request,user_obj)
return HttpResponse('登陆成功!')
return render(request,'login.html')
1.4 判断当前用户是否登录
使用request.user.is_authenticated()判断用户是否登录,返回布尔值,True/False。
def check_login(request):
if request.user.is_authenticated():
return HttpResponse('login')
else:
return HttpResponse('not login')
1.5 校验原密码是否正确
通过request.user.check_password(旧密码)来校验用户是否输入了正确的密码,返回值为布尔值True/False。
@login_required # 局部登录跳转页面配置
def check_password(request):
user_obj = request.user # 获取已经登陆的用户
if request.method == 'POST':
old_password = request.POST.get('old_password')
new_password = request.POST.get('new_password')
# 校验原来的密码是否正确 返回布尔
is_right = user_obj.check_password(old_password)
if is_right:
user_obj.set_password(new_password)
user_obj.save()
return HttpResponse('修改成功!')
return render(request,'change_password.html')
1.6 修改密码
通过request.user.set_password(新密码)来修改用户的密码,修改完成后需要执行request.user.save()来将修改后的数据写入数据库。
不然数据只是在缓存中修改了一下,没有真正写入数据库。
@login_required # 局部登录跳转页面配置
def check_password(request):
user_obj = request.user # 获取已经登陆的用户
if request.method == 'POST':
old_password = request.POST.get('old_password')
new_password = request.POST.get('new_password')
# 校验原来的密码是否正确 返回布尔
is_right = user_obj.check_password(old_password)
if is_right:
# 修改用户密码,并保存
user_obj.set_password(new_password)
user_obj.save()
return HttpResponse('修改成功!')
return render(request,'change_password.html')
1.7 注销
直接通过auth.logout(request)方法注销用户。
@login_required
def logout(request):
auth.logout(request)
return HttpResponse('用户已注销!')
1.8 校验用户是否登录装饰器
1.首先需要导入登录认证装饰器模块函数
from django.contrib.auth.decorators import login_required
2.然后可以设置未登录时跳转到登录页面的url
局部配置
@login_required(login_url='/login/')
def func(request):
pass
全局配置 (settings配置文件中 直接配置)
# settings中配置
LOGIN_URL = '/login/'
# views
@login_required
def func(request):
pass
注意:
如果全局配置了,局部也配置,将以局部的login_url为准。
2. 扩展auth_user表中的字段
2.1 利用一对一建立外键关系表
另写一张表用来存放需要添加的字段,用一对一的关系外键绑定到auth_user表上。
绑定之前需要把from django.contrib.auth.models import User自动创建的表导过来。
# models
from django.contrib.auth.models import User
class UserDetail(models.Model):
phone = models.BigIntegerField()
user = models.OneToOneField(to='User')
2.2 继承Django提供的auth类
在创建所有表之前直接修改本应该有的auth_user表。
通过继承User表的父类,自己重写新的User类。
继承之前同样需要将User父类from django.contrib.auth.models import AbstractUser导过来。
# models
from django.contrib.auth.models import AbstractUser
class Userinfo(AbstractUser):
phone = models.BigIntegerField()
register_time = models.DateField(auto_now_add=True)
注意:
自己重写类后,需要在配置文件中配置一下,不然系统不知道你要自己重写表了。
写完之后,之前所有的auth模块功能也全都可以通过你新写的表使用。
# settings
AUTH_USER_MODEL = 'app01.Userinfo' # 应用名.表名
Django之csrf中间件及auth模块使用的更多相关文章
- Django框架之中间件与Auth
Django框架之中间件与Auth模块一 cbv加装饰器 -先导入:from django.utils.decorators import method_decorator -1 可以在方法上加装饰器 ...
- Django 中CSRF中间件 'django.middleware.csrf.CsrfViewMiddleware',
1.Django中CSRF中间件的工作原理及form表单提交需要添加{% csrf_token %}防止出现403错误 CSRF # 表示django全局发送post请求均需要字符串验证功能:防止跨站 ...
- django中间件和auth模块
Django中间件 由django的生命周期图我们可以看出,django的中间件就类似于django的保安,请求一个相应时要先通过中间件才能到达django后端(url.views.template. ...
- Django CBV加装饰器、Django中间件、auth模块
一. CBV加装饰器 在视图层中,基于函数的视图叫FBV(function base views),基于类的视图叫CBV(class base views).当需要用到装饰器时,例如之前的基于Cook ...
- 中间件和auth模块
中间件 1.什么是中间件 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用 ...
- Django 自带认证功能auth模块和User对象的基本操作
一.auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: authenticate() ...
- Django的csrf中间件
csrf中间件 csrf 跨站请求伪造 补充两个装饰器: from django.views.decorators.csrf import csrf_exempt,csrf_protect ...
- python框架之Django(12)-认证系统之auth模块
我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Django作为一个完美主义者的终极框 ...
- Django 认证系统 cookie & session & auth模块
概念 cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生. cookie的工作原理是:由服务器产生内容,浏 ...
随机推荐
- ApiTesting全链路自动化测试框架 - 初版发布(一)
简介 此框架是基于Python+Pytest+Requests+Allure+Yaml+Json实现全链路接口自动化测试. 主要流程:解析接口数据包 ->生成接口基础配置(yml) ->生 ...
- 掌握数位dp
最近遇到了数位dp题目,于是就屁颠屁颠的跑过来学习数位dp了~ "在信息学竞赛中,有这样一类问题:求给定区间中,满足给定条件的某个D 进制数或此类数的数量.所求的限定条件往往与数位有关,例如 ...
- 2019牛客暑期多校训练营(第六场)J Upgrading Technology
传送门 题意: 就是给你n个技能,每个技能最高升到m级,每升一级就是耗费Cij钱,这个Cij可能是负的,如果所有技能都升到或者说超过j等级,就会获得Dj钱,这个Dj也有可能是负值,让你求你最多得到多少 ...
- Network of Schools POJ - 1236 有向强连通图
//题意://给你n个学校,其中每一个学校都和一些其他学校有交流,但是这些边都是单向的.你至少需要给几个学校//传递消息可以使全部学校都收到消息,第二问你最少添加几条边可以使它变成一个强连通图//题解 ...
- L3-007 天梯地图 (30分) 最短路+dp
最短路+dp思路:nuoyanli 520 Let's play computer game 输入样例1: 10 15 0 1 0 1 1 8 0 0 1 1 4 8 1 1 1 5 4 0 2 3 ...
- Beautiful numbers CodeForces - 55D
题意: 找出区间[li,ri]内有多少数满足,这个数的每一个位的非0数都能把这个数整除 题解: 因为这个数每一位的值都可以把这个数整除,那也就是说这个数是它所有位数的公倍数,但是可能不是最小公倍数. ...
- 【ybt金牌导航1-2-5】【luogu P3287】优美玉米 / 方伯伯的玉米田
优美玉米 / 方伯伯的玉米田 题目链接:ybt金牌导航1-2-5 / luogu P3287 题目大意 有一个数组,你可以每次给一个区间里面的值加一,要你使得最后剩下的最长单调不下降子序列最长. 思路 ...
- windows下的PyCharm设置注释字体的斜体
操作截图如下:File --> Settings --> Editor --> Color Scheme --> Language Defaults --> Commen ...
- java变量、数据类型、运算符
关键字.保留字.标识符 关键字 Java关键字是对Java编译器有特殊含义的字符串,是编译器和程序员的一个约定,程序员利用关键字来告诉编译器其声明的变量类型.类.方法特性等信息 保留字 goto.co ...
- 基金术语 All In One
基金术语 All In One GP.LP.PE.VC.FOF LP 有限合伙人(Limited Partner, LP):我们可以简单的理解为出资人. 很多时候,一个项目需要投资上千万乃至数个亿的资 ...