csrf,CBV添加装饰器的多种方式,auth认证模块,基于django中间件设计项目功能
- csrf跨网站请求伪造
-
csrf操作
-
csrf相关装饰器
-
auth模块简介
-
auth模块常见功能
-
auth_user表切换
-
基于django中间件设计项目功能
csrf跨网站请求伪造
引子-钓鱼网站:
1. 我们众所周知的钓鱼网站就是建设一个和真实网站一摸一样的网站,只不过它将提交地址变成了真实的网站地址,以假乱真 我们称之为csrf攻击
2. 既然这样危险,那么我们就要想办法解决掉,所以,现在的网站都会在你访问网站的时候会返回一个随机字符串(令牌),在我们下一次登录的时候浏览器发送请求的时候就会带上这个字符串,而假网站发送的请求由于没有令牌就会被拒绝访问(403 Forbidden)这就称之为csrf防御
3. csrf策略:通过在返回的页面上添加独一无二的标识信息从而区分正规网站和钓鱼网站的请求
csrf操作
所以上面的中间件需要结合下面的方法使用,既保证了我们自己可以访问自己的网页,也组织了外界钓鱼网站的访问
csrf操作主要是在提交的时候进行操作,我们学过提交数据的方法主要有两个:form表单,ajax
1. form表单
我们在form表单中加上模板语法{% csrf_token %}
即可
2. ajax
方式一: 先编写csrf模板语法 然后利用标签查找和值获取 手动添加
'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()
方式二: 直接利用模板语法即可
'csrfmiddlewaretoken':'{{ csrf_token }}'
方式三:通用方式(js脚本)
js脚本csrf
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
csrf相关装饰器
有的时候一个网站可以都不校验csrf,但是局部需要校验
一个网站默认都要校验csrf,但是局部有些不需要
FBV
from django.views.decorators.csrf import csrf_protect,csrf_exempt
csrf_protect 校验csrf
csrf_exempt 不校验csrf
在我们需要的时候给局部函数加上语法糖即可 @csrf_protect @csrf_exempt
CBV
针对CBV不能直接在方法上添加装饰器 需要借助于专门添加装饰器的方法
from django.utils.decorators import method_decorator
在需要装饰的函数上面使用语法糖即可
方式一:指名道姓的添加@method_decorator(两种校验方式)
方式二:指名道姓的添加:@method_decorator(csrf_protect, name='post')
方式三:影响类中所有的方法@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
super(MyHome, self).dispatch(request, *args, **kwargs)
def get(self, request):
return HttpResponse('Home Get view')
针对csrf_exempt只有方式3有效 针对其他装饰器上述三种方式都有效
auth模块简介
1. 在我们django数据库执行迁移命令的时候会创建一个auth_user表
2. 这个表可以配合auth模块做用户相关的功能(注册,登录,修改密码...)
3. 该表还是django admin后台管理默认的表
4. django admin后台管理员账号创建
python manage.py createsuperuser
auth模块常见功能
1. 创建用户
from django.contrib.auth.models import User
User.objects.create_user(username,password)
User.objects.create_superuser(username,password,email)
2. 登录功能(校验用户名和密码是否正确)
from django.contrib import auth
request.user
当用户登录成功之后(执行了auth.login) 该方法返回当前登录用户对象
当用户没有登录成功(没有执行auth.login) 该方法返回匿名用户对象
request.user.is_authenticated
判断当前用户是否登录
@login_required(login_url='/login/')
默认跳转的地址比较复杂,我们可以在括号内自定义跳转的地址
3. 用户登录
auth.login(request,user_obj)
4. 判断当前用户是否登录
request.user.is_authenticated
5. 获取登录用户对象
request.user
当用户登录成功之后(执行了auth.login) 该方法返回当前登录用户对象
当用户没有登录成功(没有执行auth.login) 该方法返回匿名用户对象
6.校验用户登录装饰器
from django.contrib.auth.decorators import login_required
6.1 跳转局部配置
@login_required(login_url='/login/')
默认跳转的地址比较复杂,我们可以在括号内自定义跳转的地址
6.2 跳转全局配置(在settings配置文件中配置)
LOGIN_URL = ‘/login/’
之后就可以直接使用@login_required
了
7. 校验密码是否正确
request.user.check_password(old_password)
8. 修改密码
request.user.set_password(new_passowrd)
request.user.save() 别忘了保存数据
9. 注销登录
auth.logout(request) 自动清除cookie和session
auth_user表切换
我们想要使用auth_user的字段同时我们还想自己拓展些新的字段
1. 我们可以在models.py中设置
from django.contrib.auth.models import AbstractUser
我们通过类的继承可以拓展一些新的字段
class Userinfo(AbstractUser):
'''扩展auth_user表中没有的字段'''
phone = models.BigIntegerField()
desc = models.TextField()
2. 同时别忘了在settings中配置一下
AUTH_USER_MODEL = 'app01.Userinfo'
基于django中间件设计项目功能
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的中间件是一个个的模块,只不过他是用字符串的方式弄了一个模块路径
在此之前我们也学过导入模块的方式
1. import 模块
2. from ... import 模块
像这种通过字符串到模块的方式我们也可以自己实现,实现自定义
s1 = 'bbb.b'
import importlib 导一个importlib模块
res = importlib.import_module(s1)
他会自动按照. 进行分割,这句话就等价于from bbb import b
res就是模块b
之后我们通过res. 的方式就能拿到模块b中的所有东西
总结:
拿到一个字符串,通过rsplit切割maxsplit=1分割字符串
这样以后我们就可以将模块放在配置文件中,方便使用
步骤:
1. 建立一个文件夹(任意名字)
2. 在这个文件夹中建一个notify,同时建立一个__init__.py文件
3. 创建类
4. 在notify文件夹下创建类/函数,同时在__init__文件中定义调用所有类的方法,因为等下导包的之后是会先执行__init__文件中的内容的
5. 在settings文件中配置我们之前创建的类名的路径和3相对应
6. 配置启动文件
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)