其他分享
首页 > 其他分享> > django框架-10

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