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

反射

通过字符串操作类和函数

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的函数中使用上面两个函数

  1. csrf_exempt这个装饰器只能给dispatch装才能生效;
  2. 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模块使用的更多相关文章

  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. CF-1332 F. Independent Set

    F. Independent Set 题意 一颗 n 个节点的树,求出每个\(edge-induced~subgraph\)的独立集个数之和. \(edge-induced~subgraph\)含义是 ...

  2. Educational Codeforces Round 86 (Div. 2)

    比赛链接:https://codeforces.com/contest/1342 A - Road To Zero 题意 有两个非负整数 x, y 以及两种操作: 支付 a 点代价使其中一个数加一或减 ...

  3. hdu 6814 Tetrahedron 规律+排列组合逆元

    题意: 给你一个n,你需要从1到n(闭区间)中选出来三个数a,b,c(可以a=b=c),用它们构成一个直角四面体的三条棱(可看图),问你从D点到下面的三角形做一条垂线h,问你1/h2的期望 题解: 那 ...

  4. 浅谈Webpack模块打包工具四

    Webpack 生产环境优化 生产环境和开发环境有很大的差异,生产环境只注重运行效率,开发环境主要开发效率,webpack4.0开始提出了(mode)模式的概念 针对不同的环境进行不同的配置,为不同的 ...

  5. 力扣567.字符串的排列—C语言实现

    题目 来源:力扣(LeetCode)

  6. 2.安装Helm

    作者 微信:tangy8080 电子邮箱:914661180@qq.com 更新时间:2019-06-25 13:54:15 星期二 欢迎您订阅和分享我的订阅号,订阅号内会不定期分享一些我自己学习过程 ...

  7. Leetcode(878)-第 N 个神奇数字

    如果正整数可以被 A 或 B 整除,那么它是神奇的. 返回第 N 个神奇数字.由于答案可能非常大,返回它模 10^9 + 7 的结果. 示例 1: 输入:N = 1, A = 2, B = 3 输出: ...

  8. 九种姿势运行Mimikatz

    https://www.freebuf.com/articles/web/176796.html

  9. Linux 驱动框架---dm9000分析

    前面学习了下Linux下的网络设备驱动程序的框架inux 驱动框架---net驱动框架,感觉知道了一个机器的大致结构还是不太清楚具体的细节处是怎么处理的,所以今天就来以dm9000这个网上教程最多的驱 ...

  10. 一个汉字在php中占几个字节?

    问:一个汉字在php中占几个字节? 答: 对于中文字符,若使用 GBK.Big-5 版本,每个中文字符相当于 2 个字节: 若使用 UTF-8 版本,每个中文字符相当于 3 个字节.