Django CSRF与auth模块

目录

  • Django CSRF与auth模块

    • CSRF
    • CSRF相关装饰器
    • auth模块
    • 扩展默认的auth_user表

Django CSRF与auth模块

CSRF

FORM表单中怎么通过CSRF校验

只需要在form表单中写一个

{% csrf_token %}

ajax通过asrf校验有三种方法

$.ajax({
            url:'',
            type:'post',
            {#data:{'username':'yang'},#}
            //第一种方式 自己手动获取
            {#data:{'username':'yang','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},#}
            //第二种方式 利用模板语法
            {#data:{'username': 'yang', 'csrfmiddlewaretoken':'{{ csrf_token }}'},#}
            //第三种方式 通用方式 需要引入外部js文件
            data:{'username':'yang'},
            success:function (data) {
                alert(data)
            }
        })

第三种需要引入外部js文件,文件中需要书写以下代码

写一个getCookie方法

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);
    }
  }
});

将上面的文件配置到你的Django项目的静态文件中,在html页面上通过导入该文件即可自动帮我们解决ajax提交post数据时校验csrf_token的问题,(导入该配置文件之前,需要先导入jQuery,因为这个配置文件内的内容是基于jQuery来实现的)


CSRF相关装饰器

from django.views.decorators.csrf import csrf_exempt, csrf_protect

应用场景:

  • 当网站整体都校验csrf的时候,想让某几个视图函数不校验
  • 当网站整体都不校验csrf的时候,想让某几个视图函数校验

csrf_exempt:不校验

csrf_protect:校验

# @csrf_exempt    # 不校验csrf
@csrf_protect   # 校验csrf
def index(request):
    print('我是视图函数index')

    def render():
        return HttpResponse('我是index里面的render函数')

    obj = HttpResponse('index')
    obj.render = render
    return obj

给FBV装饰,导入后直接加装饰器就行

但是给CBV加装饰器,有三种方式

需要导入一个方法,使用这个方法method_decorator(csrf_protect)

  1. 加在CBV视图的某个方法上
from django.views import View
from django.utils.decorators import method_decorator

class MyHome(View):

    def get(self, request):
        return HttpResponse('get')

    @method_decorator(csrf_protect)     # 第一种方式
    def post(self, request):
        return HttpResponse('post')
  1. 直接加在视图类上,但是method_decorator需要传入name关键字参数
from django.views import View
from django.utils.decorators import method_decorator

@method_decorator(csrf_protect, name='post')  # 第二种,知名道姓的给类的某个方法装饰
class MyHome(View):

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')
  1. 加在dispatch方法上

在匹配类方法之前,都需要dispatch方法分发,所以给该方法装饰,就代表整个类中的方法都是校验或不校验

from django.views import View
from django.utils.decorators import method_decorator

class MyHome(View):

    @method_decorator(csrf_protect)     # 第三种 类中所有的方法都装
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request,*args,**kwargs)

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

CBV中首先执行的就是dispatch方法,所以这么写相当于给get和post方法都加上了登录校验。

补充

CSRF Token相关装饰器在CBV只能加到dispatch方法上,或者加在视图类上然后name参数指定为dispatch方法。

  • csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
  • csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
from django.views import View
from django.utils.decorators import method_decorator

class MyHome(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request,*args,**kwargs)

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

or

from django.views import View
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch')
class MyHome(View):
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request,*args,**kwargs)

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

注意:给CBV加装饰器,推荐使用模块method_decorator,csrf_exempt只能给dispatch方法装


auth模块

Django用户相关的自带的功能模块

导入模块

from django.contrib import auth
from django.contrib.auth.models import User

auth模块常用方法:

1.创建用户
  • create()

虽然可以创建,但是密码是明文,对后面的密码校验修改密码等功能都有影响,所以不推荐使用

User.objects.create(username='用户名',password='密码',email='邮箱',...)
  • create_user()

auth提供的一个创建新用户的方法,需要提供必要参数(username, password)

User.objects.create_user(username='用户名',password='密码',email='邮箱',...)
  • create_superuser()
User.objects.create_superuser(username='用户名',password='密码',email='邮箱',...)
2.校验用户名和密码是否正确
  • authenticate()

提供了用户认证功能,需要username 、password两个关键字参数

authenticate(username='usernamer',password='password')

注意:

  • 认证成功(用户名和密码正确有效),便会返回一个 User 对象
  • 认证失败(用户名和密码不正确),便会返回一个 None
3.保存用户登录状态(session)
  • login()

可以实现一个用户登录的功能,需要一个HttpRequest对象,以及一个经过认证的User对象

def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user_obj = auth.authenticate(request, username=username, password=password)
        """
        用户名密码正确返回的是用户对象
        错误的话返回的是None
        """
        if user_obj:
            auth.login(request, user_obj)
            return HttpResponse('登录成功')
    return render(request, 'login.html')

只要执行了这个方法,之后在任意可以获取到request对象的地方,都可以通过request.user获取当前登录的对象

4.判断是否登录以及获取当前登录用户对象
  • is_authenticated()

用来判断当前请求是否通过了认证

request.user.is_authenticated() # 返回布尔值
  • request.user

获取登录用户对象

5.登录装饰器
  • login_required()

auth 给我们提供的一个装饰器工具

from django.contrib.auth.decorators import login_required

@login_required()
def is_login(request):
    pass

若用户没有登录,则会跳转到django默认的 登录URL ‘/accounts/login/ ‘ 并传递当前访问url的绝对路径 (登陆成功后,会重定向到该路径).

可以自定义登录的URL,在settings.py文件中通过LOGIN_URL进行修改

# 全局配置:
LOGIN_URL = '/login/'  # 这里配置成你项目登录页面的路由
# 局部配置:
@login_required(login_url='/login/')

若两者都配置了,优先执行局部的配置

6.判断密码是否正确
  • check_password()

auth提供的一个检查密码是否正确的方法,需要传入当前请求用户的密码,返回布尔值

is_right = request.user.check_password(old_password)
7.修改密码
  • set_password()

auth 提供的一个修改密码的方法,接收要设置的新密码

注意:一定要调用user.save方法保存

user.set_password(password='')
user.save()

修改密码的例子

@login_required()
def set_password(request):
    if request.method == 'POST':
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        is_right = request.user.check_password(old_password)# 判断旧密码是否正确
        print(is_right)
        if is_right:
            request.user.set_password(new_password) # 设置新密码
            request.user.save() # save保存
    return render(request, 'set_password.html')
8.注销功能
  • logout()

需要一个request参数,没有返回值

当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错

@login_required()
def logout(request):
    auth.logout(request)
    return HttpResponse('注销成功')

扩展默认的auth_user表

我们可以通过继承内置的AbstractUser 类,来定义一个自己的Model类,这样既能根据项目需求灵活的设计用户表,又能使用Django强大的认证系统

利用类的继承

from django.contrib.auth.models import User,AbstractUser

class UserInfo(AbstractUser):
    phone = models.CharField(max_length=11, null=True)
    avatar = models.FileField()

    def __str__(self):
        return self.username

注意:

按上面的方式扩展了内置的auth_user表之后,要在settings.py中告诉Django,我现在使用我新定义的UserInfo表来做用户认证。

写法如下:AUTH_USER_MODEL = ‘应用名.表名‘

# 引用Django自带的User表,继承使用时需要设置
AUTH_USER_MODEL = "app名.UserInfo"

再次注意:

一旦我们指定了新的认证系统所使用的表,我们就需要重新在数据库中创建该表,而不能继续使用原来默认的auth_user表了

原文地址:https://www.cnblogs.com/YGZICO/p/12198766.html

时间: 2024-10-09 19:02:51

Django CSRF与auth模块的相关文章

1205 CSRF跨站请求与django中的auth模块使用

目录 今日内容 昨日回顾 基于配置文件的编程思想 importlib模块 简单代码实现 跨站请求伪造csrf 1. 钓鱼网站 如何实现 模拟该现象的产生 2. 解决问题 解决 {% csrf_token %} 3. ajax如何解决 方式1 方式2 方式3 4. csrf相关的两个装饰器 1. 使用 2. 两个装饰器在CBV上的异同 django里settings源码剖析 django有两个配置文件 django auth模块 1. 是什么 2. 常用方法 2.1 创建用户 create_use

django 之csrf、auth模块及settings源码、插拔式设计

目录 基于django中间件拷贝思想 跨站请求伪造简介 跨站请求伪造解决思路 方式1:form表单发post请求解决方法 方式2:ajax发post请求解决方法 csrf相关的两个装饰器 csrf装饰器在CBV上的特例 django settings源码 auth模块简介 auth创建用户 auth扩展表 基于django settings配置文件实现插拔式设计 csrf:Cross Site Request Forgery protection 基于django中间件拷贝思想 # start.

CSRF与auth模块

目录 一.模拟实现中间件的编程思想 (一)impotlib模块 (二)实现功能的配置使用 二.跨站请求伪造CSRF (一)由来 (二)form表单的CSRF (三)ajax中的CSRF (1)通过data携带 (2)通过headers携带 (3)官网提供的文件(推荐用法) (四)CSRF相关的装饰器 (1)MTV模型中使用 (2)CBV模型中使用 三.Django中auth模块 (一)什么是auth模块 (二)常用方法 (1)创建用户 (2)校验用户 (3)登录保存 (4)是否登录 (5)检验密

django框架之auth模块

内容回顾    1. form表单组件        1. 常用字段            1. CharField()            2. ChoiceField()        2. 参数或配置            1. label="label标签显示的文本内容"            2. initial="默认值"            3. widget=forms.widgets.TextInput()   --> <input

django自关联,auth模块

一.自关联 写蛮好的一篇博客:https://www.cnblogs.com/Kingfan1993/p/9936541.html 1.一对多关联 1.表内自关联是指表内数据相关联的对象和表是相同字段,这样我们就直接用表内关联将外键关联设置成自身表的字段 2.例如,对于微博评论,每条评论都可能有子评论,但每条评论的字段内容应该都是相同的,并且每条评论都只有一个父评论,这就满足了一对多的情形,父评论id为关联字段,可以对应多个子评论 3.外键关联是在子评论中,有关联字段的是子评论,子评论查父评论是

Django认证系统--Auth模块

Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点.它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据. 举个例子: 用session写一个登陆 会比较麻烦 urls.py from django.contrib import admin from dj

Django中的auth模块

from django.contrib import auth authenticate() 提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username .password两个关键字参数. 如果认证成功(用户名和密码正确有效),便会返回一个 User 对象. authenticate()会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的. 用法: user = authenticate(username='usernamer',pa

Django内置auth模块中login_required装饰器用于类视图的优雅方式

使用多继承 以及类似java中的静态代理模式 原理:OrderView.as_view()根据广度优先,调用的是LoginRequiredMixin中的as_view(cls, *args, **kwargs) 这时的cls=OrderView 接下来super(LoginRequiredMixin, cls).as_view(*args, **kwargs) 会调用到View类中的as_view()并返回一个视图函数 然后,用将这个视图函数作为参数传给Login_required()并返回经过

☆Django☆---中间件 csrf跨站请求伪造 auth模块 settings功能插拔式源码

Django中间件 django生命周期图 中间件: 概念: Django中间件就类似于 django的保安   请求 的时候需要先经过中间件才能到达django后端(urls, views)   响应 走的时候也需要经过中间件才能到达web服务网关接口 django默认的七个中间件 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.Session