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. 配置启动文件

 

posted @   没错,干就完了!  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示