django 中间件,auth模块

[TOC]css

django 中间件,auth模块

django请求生命周期流程图

django中间件

前戏

在前面的博客中已经学会了给视图函数加装饰器来判断是用户是否登陆,把没有登陆的用户请求跳转到登陆页面。咱们经过给几个特定视图函数加装饰器实现了这个需求。可是之后添加的视图函数可能也须要加上装饰器,这样是否是稍微有点繁琐。

中间件

他就像至关于django的门户,通俗一点就是阻止你进门的保安,须要验证。

只要是全局相关的功能你都应该考虑使用django中间件来帮你完成html

全局用户身份校验
全局用户访问频率校验
用户访问黑名单
用户访问白名单

中间件介绍

什么是中间件:python

中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每一个中间件组件都负责作一些特定的功能。
中间件是帮助咱们在视图函数执行以前和执行以后均可以作一些额外的操做,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

注意:jquery

可是因为其影响的是全局,因此须要谨慎使用,使用不当会影响性能。

中间件代码

只要之后用django开发业务 设计到全局相关的功能 你就考虑用中间件ajax

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支持用户自定义中间件

中间件能够定义六个方法,分别是:(主要的是process_request和process_response)django

class SessionMiddleware(MiddlewareMixin):
    def process_request(self, request):

    def process_response(self, request, response):

class CsrfViewMiddleware(MiddlewareMixin):
    def process_request(self, request):

    def process_view(self, request, callback, callback_args, callback_kwargs):

    def process_response(self, request, response):


class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
以上方法的返回值能够是None或一个HttpResponse对象,若是是None,则继续按照django定义的规则向后继续执行,若是是HttpResponse对象,则直接将该对象返回给用户

自定义一个中间件示例

django运行用户自定义中间件而且暴露给用户五个能够自定义的方法

process_request

请求来的时候会按照配置文件中注册的中间从上往下的顺序依次执行每个中间件里的process_request方法,若是没有直接跳过执行下一个同级别返回,并不会所有执行process_resquest
process_request有一个参数,就是request,这个request和视图函数中的request是同样的
因为request对象是同样的,因此咱们能够对request对象进行一系列的操做,包括request.变量名=变量值,这样的操做,咱们能够在后续的视图函数中经过相同的方式便可获取到咱们在中间件中设置的值。
它的返回值能够是None也能够是HttpResponse对象。返回值是None的话,按正常流程继续走,交给下一个中间件处理,若是是HttpResponse对象,Django将不执行视图函数,而将相应对象返回给浏览器。

代码:bootstrap

process_response(*****)

相应走的时候会按照配置文件中注册的中间件从下往上的顺序依次执行每个中间件里面的process_response方法,该方法必需要有两个形参,而且须要将形参respondse返回
若是你内部本身返回了HttpResponse对象 会将返回给用户浏览器的内容替换成你本身的

1579008159401

1579008187731

同级别下

process_view

路人匹配成功执行视图函数以前触发

process_template_reponse

process_view(self, request, view_func, view_args, view_kwargs)

该方法有四个参数

request是HttpRequest对象。

view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称做为字符串。)

view_args是将传递给视图的位置参数的列表.

view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。

Django会在调用视图函数以前调用process_view方法。
它应该返回None或一个HttpResponse对象。 若是返回None,Django将继续处理这个请求,执行任何其余中间件的process_view方法,而后在执行相应的视图。 若是它返回一个HttpResponse对象,那么将不会执行Django的视图函数,而是直接在中间件中掉头,倒叙执行一个个process_response方法,最后返回给浏览器
视图函数返回的对象中必需要有render属性对应的render方法
视图函数返回的对象中必需要有render属性对应的render方法
def index(request):
    print('我是视图函数index')
    def render():
        return HttpResponse("你好啊 我是index里面的render函数")
    obj = HttpResponse("index")
    obj.render = render
    return obj

process_exception

当视图函数报错的时候自动触发
该方法两个参数:
一个HttpRequest对象

一个exception是视图函数异常产生的Exception对象


这个方法只有在视图函数中出现异常了才执行,它返回的值能够是一个None也能够是一个HttpResponse对象。若是是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,不然将默认处理异常。若是返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。

跨站请求伪造csrf

钓鱼网站

本质搭建一个跟正常网站如出一辙的页面
用户在该页面上完成转帐功能

转帐的请求确实是朝着正常网站的服务端提交
惟一不一样的在于收款帐户人不一样

给用户书写form表单 对方帐户的input没有name属性
你本身悄悄提早写好了一个具备默认的而且是隐藏的具备name属性的input
模拟钓鱼网站

要作一个网站跟他同样 效果:给用户转的钱到钓鱼网站的用户帐上去了 浏览器

解决钓鱼网站问题:session

form表单如何经过csrf校验的三种方式

form表单如何经过csrf校验
你只须要在你的form表单内写一个
{% csrf_token %}

ajax如何经过csrf校验 三种方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h2>我是正儿八经的网站</h2>
<form action="" method="post">
{#    {% csrf_token %}#}
    <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>
<button id="d1">发送ajax请求</button>


{#{% load static %}#}
{#<script src="{% static 'myset.js' %}"></script>#}
{#<script>#}
{#    $('#d1').click(function () {#}
{#        $.ajax({#}
{#            url:'',#}
{#            type:'post',#}
            {#data:{'username':'jason'},#}
{#            // 第一种方式 本身手动获取#}
             {#data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},#}
{#            // 第二种方式 利用模板语法#}
            {#data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#}
{#            // 第三种     通用方式 引入外部js文件#}
{#            data:{'username':'jason'},#}
{#            success:function (data) {#}
{#                alert(data)#}
{#            }#}
{#        })#}
{#    })#}
{#</script>#}
</body>
</html>
// 第一种方式 本身手动获取
{#data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},#}
    // 第二种方式 利用模板语法
    {#data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#}
        // 第三种     通用方式 引入外部js文件  官网提供的方式
        {% load static %}
        <script src="{% static 'myset.js' %}"></script>
        data:{'username':'jason'}

csrf相关装饰器

当咱们网站总体都校验csrf的时候 我想让某几个视图函数不校验

当咱们网站总体都不校验csrf的时候 我想让某几个视图函数校验
给CBV加装饰器 推荐你使用模块method_decorator
咱们本身写的装饰器和csrf_protect用法一致
惟独csrf_exempt是一个特例 只能给dispatch方法装

导入:框架

from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.views import View9
from django.utils.decorators import method_decorator
# @method_decorator(csrf_protect,name='post')  # 第二种指名道姓的给类中某个方法装
# @method_decorator(csrf_exempt,name='post')  # csrf_exempt 第二种方式不行
@method_decorator(csrf_exempt,name='dispatch')  # 能够!!!
class MyHome(View):  # APIView
    # @method_decorator(csrf_protect)  # 第三种 类中全部的方法都装
    # @method_decorator(csrf_exempt)  # csrf_exempt 第三种方式能够
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request,*args,**kwargs)

    def get(self,request):
        return HttpResponse('get')
    # @method_decorator(csrf_protect)  # 第一种方式
    # @method_decorator(csrf_exempt)  # csrf_exempt 第一种方式不行
    def post(self,request):
        return HttpResponse('post')

auth模块

建立表

django用户相关的自带的功能模块   auth_user表

如何建立超级用户

createsuperuser

模块导入

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

auth方法大全

1.建立用户

User.objects.create()  # 密码是明文
User.objects.createuser()  # 基本都用它 
User.objects.createsuperuser()  # 邮箱要给数据

2.校验用户名和密码是否正确

auth.authenticate(username=username,password=password)  # 用户名和密码两个一个都不能少
# 该方法当用户名和密码正确的时候返回的用户对象 不正确返回None

3.保存用户登陆状态

auth.login(request,user_obj)  # 这一句执行以后 request.user获取当前登陆的用户对象

4.如何判断当前用户是否登陆 以及如何获取当前登陆用户对象

request.user.is_authenticated()  # 判断是否登陆
request.user  # 登陆用户对象

5.校验用户是否登陆

局部配置 全局配置
from django.contrib.auth.decorators import login_required
# 局部配置
@login_required(login_url='/login/')
def xxx(request):
    return HttpResponse('xxx页面')

# 全局配置
配置文件中写如下代码
LOGIN_URL = '/login/'
@login_required
def xxx(request):
    return HttpResponse('xxx页面')

# 若是两个都设置了 那么优先执行局部配置

6.修改密码

request.user.check_password(old_password)  # 校验原密码是否正确

request.user.set_password(new_password)
request.user.save()                        # 必定要保存

7.注销功能

auth.logout(request)

如何扩展auth_user表

1 利用一对一表关系()

2 利用类的继承

# 2 利用类的继承
# 1 类的继承
from django.contrib.auth.models import User,AbstractUser
# Create your models here.
class Userinfo(AbstractUser):
    phone = models.BigIntegerField()
    avatar = models.FileField()
    # 扩展的字段 尽可能不要与原先表中的字段冲突

    # 2 配置文件
    AUTH_USER_MODEL = '应用名.表名'

总结:

django就会将userinfo表来替换auth_user表
而且以前auth模块全部的功能不变 参照的也是userinfo表
相关文章
相关标签/搜索