Django之csrf和cbv
2022/9/14 6:19:03
本文主要是介绍Django之csrf和cbv,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
csrf跨站请求伪造
介绍
1.简介 钓鱼网站:假设是一个跟银行一模一样的网址页面 用户在该页面上转账 账户的钱会减少 但是受益人却不是自己想要转账的那个人 2.模拟 一台计算机上两个服务端不同端口启动 钓鱼网站提交地址改为正规网站的地址 3.预防 csrf策略:通过在返回的页面上添加独一无二的标识信息从而区分正规网站和钓鱼网站的请求
模拟钓鱼网站和真实网站
# 真实网站 def transfer(request): if request.method == 'POST': username = request.POST.get('name') target_name = request.POST.get('target_name') money = request.POST.get('money') print(f'{username}给{target_name}转了{money}钱') return render(request,'transfer.html') 前端代码: <h1>真网站</h1> <form action="" method="post"> <p>name: <input type="text" name="name"></p> <p>target_name : <input type="text" name="target_name"></p> <p>money : <input type="text" name="money"></p> <input type="submit"> </form>
# 钓鱼网站: def transfer(request): return render(request,'transfer.html') 前端代码: <h1>钓鱼网站</h1> <form action="http://127.0.0.1:8000/transfer/" method="post"> <p>name: <input type="text" name="name"></p> <p>target_name : <input type="text" > <input type="text" name="target" value="jerry" style="display: none"> </p> <p>money : <input type="text" name="money"></p> <input type="submit"> </form>
csrf操作(解决措施)
'''先打开settings里面的MIDDLEWARE的第四行'django.middleware.csrf.CsrfViewMiddleware'''' 全局校验 需要携带一串随机字符串验证通过才可以朝服务端发送post请求
![image](https://img20
form表单方法: 1.给form表单内部添加方法 <form action="" method="post"> {% csrf_token %} # 前后端分离的时候用不了这个方法 </form> # 这时候就会产生一串随机字符串 当提交post请求的时候 服务端会自动校验身份
Ajax方法: # 方法1:先编写csrf模板语法 然后利用标签查找和值获取 手动添加 {% csrf_token %} <button id=" d1">ajax</button> <script> $('#d1').click(function () { $.ajax({ url: '', type: 'post', data: {'username': 'summer', 'csrfmiddlewaretoken': $('[name = "csrfmiddlewaretoken"]').val()}, success:function (args){ } }) }) </script> # 方法2:直接利用模板语法 data:{'username': 'summer', 'csrfmiddlewaretoken':'{{csrf_token}}'}, # 方法3:js脚本(通用方法) 扩展性最高 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); } } }); # 直接拷贝代码放在静态文件目录的js文件夹内即可
csrf相关装饰器
1.当整个网站默认都不校验csrf 但是局部视图函数需要校验 如何处理 # 注掉settings里面的MIDDLEWARE的第四行代码 2.当整个网站默认都校验csrf 但是局部视图函数不需要校验 如何处理
# FBV from django.views.decorators.csrf import csrf_exempt, csrf_protect @csrf_protect # csrf校验 def home(request): return HttpResponse('下午好啊,北鼻!') ''' csrf_exempt 不校验csrf csrf_protect 校验csrf '''
CBV添加装饰器的多种方式
# CBV from django import views from django.utils.decorators import method_decorator # @method_decorator(csrf_protect , name='post') # 方式2 可以指定给哪个方法装 class MyHome(views.View): @method_decorator(csrf_protect) #方式3 影响类中的所有方法 def dispatch(self, request, *args, **kwargs): super(MyHome, self).dispatch(request, *args, **kwargs) def get(self, request): return HttpResponse('home get view') # @method_decorator(csrf_protect) # 方式1 def post(self, request): return HttpResponse('home post view') ''' 针对CBV不能直接在方法上添加装饰器 需要借助于专门添加装饰器的方法 from django.utils.decorators import method_decorator ''' # @method_decorator(csrf_exempt) 针对不校验csrf只有继承的dispatch方法可以使用
auth认证模块
django执行数据库迁移命令以后会产生一个auth_user表 基于这张表可以创建一个管理员用户 python manage.py createsupersuer 该表可以配合auth模块操作用户相关的功能:注册 登录 删除 修改等
auth模块常见功能
1.创建用户 from django.contrib.auth.models import User user.object.create_user(username,password) user.object.create_superuser(username,password,email) 2. 校验用户名和密码是否正确 from django.contrib import auth auth.authenticate(request,username,password) 3.用户登录 auth.login(request,user_obj) 4.判断用户是否登录 request.user.is_authenticated 5.获取登录用户对象 request.user 6.校验用户登录装饰器 from django.contrib.auth.decorators import login_required 跳转局部配置 login_required(login_url='/login/') 跳转全局配置 在settings里面配置需要跳转的页面 适合操作量大的数据 LOGIN_URL = '/login/' 7.检验密码是否正确 request.user.check_password(old_password) 8.修改密码 request.user.set_password(new_password) request.user.save() 9.注销登录 auth.logout(request)
代码实现
from django.contrib import auth from django.contrib.auth.decorators import login_required def login(request): print(request.user) ''' request.user 该方法登录成功(auth.login)会返回一个当前登录对象 没有登录(auth.login)会返回一个AnonymousUser 匿名用户对象 ''' print(request.user.is_authenticated) # 判断当前用户是否登录 返回的是布尔值 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) # 该方法返回的是对象 如果没有则返回None if user_obj: # 记录用户登录状态 auth.login(request, user_obj) # 自动创建session表 返回随机字符串给前端 return render(request, 'login.html') @login_required(login_url='/login/') # 局部配置 每次都需要自己写 def index(request): return HttpResponse('登录index') @login_required(login_url='/login/') def func(request): return HttpResponse('登录func') @login_required def set_password(request): if request.method == 'POST': old_password = request.POST.get('old_password') new_password = request.POST.get('new_password') # 1.校验原密码是否正确 res = request.user.check_password(old_password) if res: # 修改密码 request.user.set_password(new_password) # 保存密码 request.user.save() return render(request,'set_password.html') @login_required def logout(request): auth.logout(request) # 自动清除cookie和session return HttpResponse('注销功能') from django.contrib.auth.models import User def register(request): User.objects.create_user(username='summer',password=123) # 创建普通用户 User.objects.create_superuser(username= 'jerry',password=123,email='123@qq.com') # 创建管理员用户 return HttpResponse('注册功能')
auth_user表切换
# 想创建更多的表的字段 相当于自定义auth_user表 第一步: from django.contrib.auth.models import AbstractUser class Userinfo(AbstractUser): phone = models.BigIntegerField() desc = models.TextField() 第二步: 在settings中配置 AUTH_USER_MODEL = 'app01.Userinfo' auth模块的功能都可以用 除了自己创建的字段 其他的都一样操作
基于django中间件设计项目功能
import importlib # 功能是通过字符串来导模块 s1 = 'b.ddd' res = importlib.import_module(s1) # from b import ddd print(res.s) # 导入模块的底层原理 : 首先拿到字符串 按最右边的切割 s1.rsplit('.',maxsplit=1) 右边的单位最小为py文件 切完结果 ['b', 'ddd']
函数封装 def send_qq(content): print('qq消息通知:',content) def send_we(content): print('微信消息通知:',content) def send_msg(content): print('短信消息通知:',content) def send_all(content): send_qq(content) send_we(content) send_qq(content) if __name__ == '__main__': send_all('放假通知!!!')
配置文件插拔式设计
# 创建settings.py文件 模仿中间件 NOTIFY_FUNC_LIST = [ 'notifys.notify.qq.QQ', 'notifys.notify.weixin.Weixin', 'notifys.notify.msg.Msg', ]
# 创建需要发送消息的py文件 class QQ(object): def __init__(self): pass def send(self,content): print('qq消息通知:',content)
自定义一个文件 创建一个__init__.py # __init__.py 代码 import importlib import settings def send_all(content): for i in settings.NOTIFY_FUNC_LIST: module_path, class_str_name = i.rsplit('.', maxsplit=1) module = importlib.import_module(module_path) class_name = getattr(module, class_str_name) # 真正的类名 obj = class_name() obj.send(content)
这篇关于Django之csrf和cbv的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-15SendGrid 的 Go 客户端库怎么实现同时向多个邮箱发送邮件?-icode9专业技术文章分享
- 2024-11-15SendGrid 的 Go 客户端库怎么设置header 和 标签tag 呢?-icode9专业技术文章分享
- 2024-11-12Cargo deny安装指路
- 2024-11-02MongoDB项目实战:从入门到初级应用
- 2024-11-01随时随地一键转录,Google Cloud 新模型 Chirp 2 让语音识别更上一层楼
- 2024-10-25Google Cloud动手实验详解:如何在Cloud Run上开发无服务器应用
- 2024-10-24AI ?先驱齐聚 BAAI 2024,发布大规模语言、多模态、具身、生物计算以及 FlagOpen 2.0 等 AI 模型创新成果。
- 2024-10-20goland工具下,如修改一个项目的标准库SDK的版本-icode9专业技术文章分享
- 2024-10-17Go学习:初学者的简单教程
- 2024-10-17Go学习:新手入门完全指南