django框架-10
作者:互联网
csrf跨站请求伪造
1.简介
钓鱼网站:假设是一个跟银行一模一样的网址页面 用户在该页面上转账 账户的钱会减少 但是受益人却不是自己想要转账的那个人
2.模拟
一台计算机上两个服务端不同端口启动 钓鱼网站提交地址改为正规网站的地址
3.预防
csrf策略:通过在返回的页面上添加独一无二的标示信息 从而区分正规网站和钓鱼网站的请求
真正网站的代码
前端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h2>这是真正的网站</h2>
<form action="" method="post">
<p>username:
<input type="text" name="username">
</p>
<p>target_user:
<input type="text" name="target_user">
</p>
<p>money:
<input type="text" name="money">
</p>
<input type="submit">
</form>
</body>
</html>
后端:
from django.shortcuts import render
# Create your views here.
def transfer(request):
if request.method == 'POST':
username = request.POST.get('username')
target_user = request.POST.get('target_user')
money = request.POST.get('money')
print(f'{username}给{target_user}转了{money}')
return render(request, 'transfer.html')
路由:
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('transfer/', views.transfer),
]
"钓鱼"网站的代码
前端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h2>快看啊!!!钓鱼网站!!!</h2>
<form action="http://127.0.0.1:8000/transfer/" method="post">
<p>username:
<input type="text" name="username">
</p>
<p>target_user:
<input type="text">
<input type="text" name="target_user" value="哎呀喂" style="display: none">
</p>
<p>money:
<input type="text" name="money">
</p>
<input type="submit">
</form>
</body>
</html>
后端:
from django.shortcuts import render
# Create your views here.
def transfer(request):
if request.method == 'POST':
username = request.POST.get('username')
target_user = request.POST.get('target_user')
money = request.POST.get('money')
print(f'{username}给{target_user}转了{money}')
return render(request, 'transfer.html')
路由:
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('transfer/', views.transfer),
]
csrf操作
1.form表单
<form action="" method="post">
{% csrf_token %}
</form>
2.ajax
方式1:先编写csrf模板语法 然后利用标签查找和值获取 手动添加
'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()
方式2:直接利用模板语法即可
'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);
}
}
});
csrf相关装饰器
当整个网站默认都不校验csrf,但是局部视图函数需要校验,如何处理
csrf_protect 校验csrf
当整个网站默认都校验csrf,但是局部视图函数不需要校验,如何处理
csrf_exempt 不校验csr
FBV操作
from django.views.decorators.csrf import csrf_protect,csrf_exempt
"""
csrf_protect 校验csrf
csrf_exempt 不校验csrf
"""
# @csrf_protect
@csrf_exempt
def home(request):
return HttpResponse('铁铁 在干嘛')
CBV操作
针对CBV不能直接在方法上添加装饰器 需要借助于专门添加装饰器的方法
# @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')
注意!!!
针对csrf_exempt只有方式3有效 针对其他装饰器上述三种方式都有效
auth认证模块
django执行数据库迁移命令后会产生一个auth_user表,该表可以配合auth模块做用户相关的功能,eg:注册、登录、修改密码、注销...。该表还是django admin后台管理默认的表
django自带的admin后台管理用户登录参考的就是auth_user表
创建admin后台管理员用户 python manage.py createsuperuser 自动对用户密码进行加密处理并保存
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_authecticated
5.获取登录用户对象
request.user
6.校验用户登录装饰器
from django.contrib.auth.decorators import login_required
跳转局部配置
login_required(login_url='/login/')
跳转全局配置
LOGIN_URL = '/login/'
7.校验密码是否正确
request.user.check_password(old_password)
8.修改密码
request.user.set_password(new_passowrd)
request.user.save()
9.注销登录
auth.logout(request)
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.py
AUTH_USER_MODEL = 'app01.Userinfo'
基于django中间件设计项目功能
importlib模块:可以通过字符串的形式导入模块
常规导入方式
方式1:import 句式
方式2:from ... import ... 句式
from bbb import b
from bbb.b import name # 可以直接导变量数据
print(b) # <module 'bbb.b' from '/Users/jiboyuan/PycharmProjects/day64_1/bbb/b.py'>
print(b.name)
字符串导入方式
import importlib
module_path = 'bbb.b'
res = importlib.import_module(module_path)
print(res.name)
module_path1 = 'bbb.b.name'
importlib.import_module(module_path1) # 不可以 最小导入单位是模块文件级别
以发送提示信息为需求编写功能的案例
简单的函数式封装和配置文件插拔式设计
# settings
NOTIFY_FUNC_LIST = [
'notify.qq.QQ',
'notify.email.Email',
'notify.msg.Msg',
'notify.weixin.WeiXin',
]
# __init__
import settings
import importlib
def send_all(msg):
# 1.循环获取配置文件中字符串信息
for str_path in settings.NOTIFY_FUNC_LIST: # 'notify.qq.QQ'
# 2.切割路径信息
module_path, class_str_name = str_path.rsplit('.', maxsplit=1) # ['notify.qq','QQ']
# 3.根据module_path导入模块文件
module = importlib.import_module(module_path) # from day64.notify import qq
# 4.利用反射获取模块文件中对应的类名
class_name = getattr(module, class_str_name) # Email Msg QQ
# 5.实例化
obj = class_name()
# 6.调用发送消息的功能
obj.send(content)
标签:10,name,框架,request,django,user,csrf,import 来源: https://www.cnblogs.com/zzjjpp/p/16690491.html