ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

django框架-10

2022-09-13 22:33:14  阅读:304  来源: 互联网

标签:10 name 框架 request django user csrf import


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有