Django开发

安装与运行

安装Django

pip install django

可以执行以下命令检查Django是否安装完成,并查看安装版本

python -m django --version

创建Django项目

新建一个文件夹作为项目的目录,然后进入到该目录中,执行以下命令创建Django项目目录

django-admin startproject 项目名称

使用pycharm打开的项目结构如下图所示:

项目结构梳理

  • manage.py 是一个工具脚本,用作项目管理的,可以使用它执行管理操作

  • login 是python包的目录,里面包含项目的重要配置文件,这个目录名字不能随便改,因为manage.py要用到它

  • login/settings.py 是Django项目的配置文件

  • login/urls.py 里面存放了一张表,声明了前端发过来的各种http请求,分别由哪些函数处理

  • login/wsgi.py 提供给wsgi web server调用的接口文件,里面的application对应对象实现了wsgi入口,供wsgi web server调用 。

wsgi

Python组织制定了Web服务网关接口(Web Server Gateway Interface)规范,简称wsgi。遵循wsgi规范的Web后端系统,我们可以理解成由两个部分组成,wsgi web serverwsgi web application,它们通常是运行在一个python进程中的两个模块(子系统)。

  • wsgi web server 接收到后端的http 请求后,会调用wsgi web application的接口方法,由 wsgi web application 具体处理该请求。然后把处理结果返回给wsgi web serverwsgi web server再返回给前端

需要有两个子系统的原因
  • wsgi web server 负责 提供高效的http请求处理环境 ,可以使用多线程、多进程或协程的机制。 http 请求发送到wsgi web serverwsgi web server 分配线程或进程或协程,然后在这些线程、进程或协程去调用执行wsgi web application的入口代码。

  • wsgi web application 被调用后,负责处理业务逻辑djangowsgi web application 的框架,它只有一个简单的单线程 wsgi web server,供调试时使用。

运行Djano Web服务

​ Django虽然只是wsgi web application 的框架,但是它也有一个简单的 wsgi web server供调试使用,所以也构成一个完成的后端Web服务,本地调试代码的时候,完全可以运行起来。进入到项目根目录,在这里是 login目录里,执行以下命令

python manage.py runserver 0.0.0.0:端口号 --noreload

端口号不能被其他应用占用,否则会出现“以一种访问权限不允许的方式做了一个访问套接字的尝试。”的错误

–noreload 可以显示print语句,可用于调试,但每改变一次代码就需重新运行命令

这样服务就会被启动,我们就可以在浏览器访问Web服务了。其中0.0.0.0 是指Web服务绑定的IP地址和端口。0.0.0.0 表示绑定本机所有的IP地址,就是可以通过任何一个本机的IP(包括环回地址 127.0.0.1)都可以访问此服务。

启动后通过浏览器访问以上网址可得到以下页面:

访问本机IP地址出现以下页面,需要将login/settings中的ALLOWED_HOSTS

ALLOWED_HOSTS = ['本机IP']
ALLOWED_HOSTS = ['192.168.88.102','localhost']

创建项目app

Django中的一个app就是项目里面的一个应用。一个项目包含多个app,一个app通常就是一个相对独立的模块,实现相对独立的功能。比如,我们可以把管理员执行的操作放在一个app里,普通用户放在一个app里。

一个app本质上就是一个Python包,里面包含了一些应用相关的代码文件。

Django中创建app 可以通过执行命令,创建一个app目录,并在里面自动创建app常用的文件,我们进入根目录,执行以下命令就可新建一个app项目

python manage.py startapp manager

manager 是app名,可自定义

这样就会创建一个目录名为manager , 对应一个名为manager的app,里面 包含如下自动生成的文件:

### 返回页面内容给浏览器

服务器让浏览器呈现出网页内容:当我们输入网址后,浏览器会发送httpi请求给网址域名所在的服务器,此服务器返回HTML文档内容给浏览器,浏览器解析后,呈现出我们最终看到的网页内容。服务器返回的HTML文档内容其实就是符合HTML语法 的 一段字符串

我们在上面创建的 manager/views.py 文件,这个文件通常是写处理http请求的代码的。比如我们设计凡是浏览器访问的http请求的url地址是/api/manager/names,就由 view.py 里面的函数 listnames 来处理,返回一段字符串给浏览器

1. 构造处理函数

from django.http import HttpResponse
def listnames(request):
    return HttpResponse("下面是系统中所有用户的信息")
  • 这里最终返回结果是 HttpResponse 对象的参数字符串,也就是 HttpResponse() 中字符串的内容
  • listnames的参数request是Django中的 HttpQuest 对象,包含了请求中的信息。

2.设置路由

由urls.py一个文件控制

所有路由访问都只由urls.py 控制

打开 login/urls.py ,添加路由信息

from manager.views import listnames
urlpatterns = [
    path('manager/names/',listnames),
]
分类控制(推荐使用)

访问 manager/names, manager/names2 等的Http请求由manager文件夹下的一个文件统一进行路由控制,新建一个manager/urls.py 文件。进行以下操作:

login/urls.py

from django.urls import path,include
urlpatterns = [
    path('manager/',include("manager.urls")),#凡是以manager开头的url都去使用manager.urls文件中的路由表
]

manager/urls.py

from django.urls import path
from manager.views import listnames1,listnames2

urlpatterns = [
    path('names1/',listnames1), #访问api/manager/names1的请求由listnames1函数处理 
    path('names2/',listnames2),
]

manager/views.py

from django.http import HttpResponse
def listnames1(request):
    return HttpResponse("下面是系统中所有用户的信息1")

def listnames2(request):
    return HttpResponse("下面是系统中所有用户的信息2")

创建数据库

Sqlite

sqlite 没有独立的数据库服务进程,数据操作被做成库直接供引用程序调用。Django 中可以直接使用,无须先搭建数据服务。

创建数据库

Django 中数据库的配置在login/settings.py 中:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

我们使用命令创建的项目,缺省就是使用sqlite,对于数据库文件,缺省的文件名是 db.splite3 位于项目的根目录之下,执行以下命令,就会在项目的根目录下生成一个配置文件中指定的数据库文件db.splite3:

python manage.py migrate

sqlitestudio是sqlite的可视化工具,下载后解压并运行,打开上述db.splite3文件就查看数据库当前的表有哪些

ORM

Django 里,数据库的操作,包括数据的增删改查,基本都是通过 Model 类型的对象进行的。通常,在Django中:

  • 定义一张数据表,就是定义一个继承自 django.db.models.Model 的类
  • 定义该表中的字段(列),就是定义该类中的一些属性
  • 类的方法就是对该表中数据的处理方法,包括数据的增删改查

这样,对数据库的访问,就从原来的使用底层sql语句,变成面向对象的开发,通过一系列对象的类定义和方法调用就可以操作数据库,这样做的优点是:

  • 提高开发效率
  • 屏蔽了不同的数据库访问的底层细节,基本做到开发好代码后,如果要换数据库,几乎不需要改代码,修改几个配置项就行

这种通过对象操作数据库的方法被称之为ORM(Object Relational Mapping)

定义我们的数据库表

首先,我们创建一个名为common的app目录,里面存放我们项目需要的一些公共的表的定义。进入根目录执行以下命令,创建common app项目

python manage.py startapp common

Django 是通过定义类来定义数据库表的,我们要定义数据库的表,只需在app目录下定义特殊的类就可以了。一般来说,数据库表的定义是放在app目录下的models.py 里。在models.py 中加入以下内容:

from django.db import models

class User(models.Model):
    #用户名
    name = models.CharField(max_length=6)
    #用户密码
    password = models.CharField(max_length=200)

这个User类继承自django.db.models.Model ,用来定义数据库表,其中的name,password 是自定义的三个字段。

定义表中的字段就是定义一些静态属性,这些属性是django.db.models 里面的各种Field对象,对应不同类型的字段。Django有很多字段对象类型,对应不同的类型的数据库字段。(可参考Django官方文档)

创建数据库表

定义好数据库表后,我们要告诉Django需要关注我们的common应用,因为其中包含了数据库Model 的定义,在项目的配置文件login/settings.py 中,INSTALLED_APPS 配置项加入以下内容:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    #common
    'common.apps.CommonConfig',
]

common.apps.CommonConfig 告诉Django, CommonConfigcommon/apps.py 文件中定义的一个应用配置类:

from django.apps import AppConfig
class CommonConfig(AppConfig):
    name = 'common' #定义应用的python模块路径

修改数据库表

现在Django知道了我们的common应用,我们可以在项目根目录下执行命令:

python manage.py makemigrations common

上述操作只是产生了一个修改的代码文件,要把修改真正提交到数据库,需要继续执行下列命令:

python manage.py migrate

点击刷新后,数据库中出现common_user的表:

如果需要在该表中添加新的字段,需要在common/models.py 中加入以下内容:

qq = models.CharFields(max_length=30,null=True,blank=True)

null参数表示可以为空,blank表示可以接收空字符串

再执行上述两条命令。

对auth_user表进行操作的方法参考(https://blog.csdn.net/qq_31455841/article/details/109295785)

修改auth_user表

修改auth_user表要确保删除所有原始数据库信息(删除db.sqlite3以及所有migrations文件夹的文件),或者再未对数据库进行初始化之前就修改

新建一个app项目,在该app项目的models.py写下:

#重新定义auth_user表
from django.db import models
from django.contrib.auth.models import AbstractUser

class UserInfo(AbstractUser):
    user_key = models.CharField(max_length=100,unique=True,blank=False)  #在原本auth_user表的基础上增加一个user_key字段

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'common.apps.CommonConfig'   #注册
]
AUTH_USER_MODEL="common.UserInfo"  #app项目名.类名,auth_user表指定使用该模型

最后执行以下命令:

python manage.py makemigrations common
python manage.py migrate

Django Admin 管理数据

创建超级管理员

Django提供了一个管理员操作界面可以方便的添加、修改、删除你定义的model表的数据。首先,我们需要创建一个超级管理员账号。进入到项目根目录,执行如下命令,依次输入要创建的超级管理员的登录名、email、密码。

python manage.py createsuperuser  #密码至少需要八个字符

修改配置文件

修改应用里面的管理员配置文件 common/admin.py ,注册我们定义的model类,这样Django才会知道我们创建的User数据表:

from django.contrib import admin
from .models import User

admin.site.register(User)

然后重新启动项目访问http://服务器IP端口/admin,输入刚才注册的超级管理员的用户名和密码,就可对项目的数据库进行可视化操作

读取数据库数据

获取全部数据

现在我们来实现一个功能:浏览器访问manager/users/ 我们的服务器就返回系统中所有的客户记录给浏览器。通过上面的学习,我们直接对处理http请求的函数进行处理:

manager/views.py

from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse
from common.models import User  #引用数据表User对象

def listUsers(request):
    qs = User.objects.values() #obejcts对应数据库操作,value()方法返回一个QuerySet对象,由Django定义,包含所有的Use表的记录
    resStr = '' #定义返回字符串

    for user in qs:
        for key,value in user.items():
            resStr += f'{key}:{value} '
        resStr += '<br>'  #换行
    return HttpResponse(resStr)

修改 manager/urls.py 文件即可

过滤条件

有时我们需要根据过滤条件查询部分客户信息,比如用户输入 /manager/users/?name=11673 要求返回用户名为11673的用户记录。此时需要通过 filter 方法加入过滤条件,修改manager/views.py 文件如下:

from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse
from common.models import User  #引用数据表User对象

def listUsers(request):
    qs = User.objects.values() #返回一个QuerySet对象,由Django定义,包含所有的Use表的记录
    resStr = '' #定义返回字符串

    nameFilter = request.GET.get('name',None) #检查url中是否有参数name
    if nameFilter:
        qs = qs.filter(name=nameFilter)

    for user in qs:
        for key,value in user.items():
            resStr += f'{key}:{value} '
        resStr += '<br>'  #换行
    return HttpResponse(resStr)

对资源的增删改查处理

采用前后端分离的架构开发,后端不负责任何展现界面工作,而是负责对数据进行管理。数据管理,主要就是响应前端请求,对数据资源的增删改查。此处的增删改查是基于我们自己创建的数据库表,不适用于auth_user数据库表,即此部分实现的内容为管理员对自定义数据库表进行增删改查操作

Django的url路由功能不支持直接根据HTTP请求的方法和请求体里面的参数进行路由。

在此项目中,增删改查为管理员权限,所以都在manager 项目app文件夹中进行操作

临时取消CSRF校验

Django缺省创建的项目,会启用一个CSRF(跨站请求伪造) 安全防护机制.

在这种情况下,所有的POST、PUT类型的请求都必须在HTTP请求中携带用于校验的数据。

为了简单起见,我们先临时取消掉CSRF的校验机制,等以后有需要再打开。

取消校验机制,只需注释掉 login/settings.py 中的 MIDDLEWARE 配置项的:

'django.middleware.csrf.CsrfViewMiddleware',

自己编写dispatcher函数

鉴于Django的上述特性,我们可以自己编写一个函数,来根据http请求的类型和请求体里面的参数分发(或者说路由)给不同的函数进行处理。

manager/action.py

def dispatcher(request):
    json = checkout.checkToken(request)  # 验证token合法性
    # 根据token判断用户是否为登录的管理员
    if json['flag'] == 0:
        userInfo = json['payload']  # token信息
        userId = userInfo['user_id']
        user = User.objects.get(id=userId)  # 获取信息
        if user.is_superuser:
            bodys = str(request.body, encoding='utf-8')  # 获取request请求体
            bodys = bodys.replace('=', ':')
            body = bodys.split('&')
            # 将list转为json
            keys = []
            values = []
            for item in body:
                item = item.split(':')
                keys.append(item[0])
                values.append(item[1])
            bodyJson = dict(zip(keys, values))
            if 'action' in keys:
                action = bodyJson['action']
                if action == 'list_customer':
                    return listCustomer(request)  # 处理函数
                elif action == 'add_customer':
                    return addCustomer(request)
                elif action == 'modify_customer':
                    return modifyCustomer(request)
                elif action == 'delete_customer':
                    return deleteCustomer(request)
                else:
                    return JsonResponse({'ret': 1, 'msg': '不支持该类型http请求'})  # 转换成json形式'
            else:
                return JsonResponse({'ret': 1, 'msg': '没有action字段'})
        else:
            return JsonResponse({'ret': 1, 'msg': '非管理员'})
    else:
        return JsonResponse({'flag': json['flag'], 'msg': 'TokenError'})

login/urls.py 主路由文件

 path('manager/',include("manager.urls"))

manager/urls.py 管理员路由文件

from manager import action

urlpatterns = [
    path('customers',action.dispatcher),
]

展示用户

以统一的json格式给前端返回信息:

{'ret':0, 'retlist':[{用户信息1}, {用户信息2}]

manager/action.py

def listCustomer(request):
    qs = User.objects.values()  # 获取数据表信息
    retlist = list(qs)
    return JsonResponse({"ret": 0, "retlist": retlist})

添加用户

manager/action.py

def addCustomer(request):
    # 从post请求获取用户名、密码
    userName = request.POST.get("username")
    passwd = request.POST.get("password")
    email = request.POST.get('email')
    if userName and passwd and email:
        try:
            user = User.objects.create_user(username=userName, password=passwd, email=email)
            return JsonResponse({'ret': 0, 'msg': '添加成功'})
        except IntegrityError:
            return JsonResponse({'ret': 1, 'msg': '用户已存在'})

    else:
        return JsonResponse({'ret': 2, 'msg': '信息不足'})

修改用户

修改用户使用用户id来区别不同用户,前端需要提供用户的ID以及修改的数据

def modifyCustomer(request):
    userId = request.POST.get("id")
    if not userId:
        return JsonResponse({'ret': 1, 'msg': '无id'})
    try:
        customer = User.objects.get(id=userId)
    except User.DoesNotExist:
        return {"ret": 1, "msg": "用户不存在"}
    bodys = str(request.body, encoding='utf-8')  # 获取request请求体
    bodys = bodys.replace('=', ':')
    body = bodys.split('&')
    # 将list转为json
    keys = []
    values = []
    for item in body:
        item = item.split(':')
        keys.append(item[0])
        values.append(urllib.parse.unquote(item[1]))  # 对url编码的字符进行解码
    bodyJson = dict(zip(keys, values))
    # print("hhhhhhhhh",bodyJson)
    if 'username' in keys:
        try:
            # print("asddadsa")
            customer.username = bodyJson['username']
        except IntegrityError:
            return JsonResponse({'ret': 1, 'msg': '已有用户名'})
    if 'password' in keys:
        customer.password = bodyJson['password']
    if 'email' in keys:
        customer.email = bodyJson['email']
    try:
        customer.save()  # 将信息保存到数据库
    except:
        return JsonResponse({'ret': 1, 'msg': '用户已存在'})
    return JsonResponse({'ret': 0, "msg": "已修改用户的信息"})

删除用户

前端只需提供要删除的用户ID

# 删除用户
def deleteCustomer(request):
    bodys = str(request.body, encoding='utf-8')  # 获取request请求体
    bodys = bodys.replace('=', ':')
    body = bodys.split('&')
    # 将list转为json
    keys = []
    values = []
    for item in body:
        item = item.split(':')
        keys.append(item[0])
        values.append(item[1])
    bodyJson = dict(zip(keys, values))
    if 'username' in bodyJson:

        username = bodyJson['username']
        try:
            customer = User.objects.get(username=username)  # 查找id用户
            customer.delete()
            return JsonResponse({'ret':0,'msg':'删除成功'})
        except User.DoesNotExist:
            return JsonResponse({'ret': 1, 'msg': '用户不存在'})

    else:
        return JsonResponse({'ret': 1, 'msg': '需要用户名'})

实现登录/登出

请求参数

http请求消息body中 参数是以格式 x-www-form-urlencoded 存储,需要携带usernamepassword 两个参数

  • username=xxxx&password=xxxx

Django存储的密码是以HASH算法加密的,所以比对密码需要对密码进行HASH操作再比对

Django项目创建后,会自动创建auth_user表,以auth_user表中的 is superuser 字段判断是否为超级管理员

管理员登录代码

在管理员对应的项目目录下新增 sign_in_out.py 文件

manager/sign_in_out.py

#登录
def signin(request):
    #从HTTP POST请求中获取用户名、密码参数
    userName = request.POST.get("username")
    passWord = request.POST.get("password")
    #使用Django auth库里的方法校验用户名、密码
    user = authenticate(username=userName,password=passWord)
    # print("id",user.id)
    '''
    ret 0 : 普通用户登录成功
        1 : 登录失败
        2 : 管理员登录成功
    '''
    #如果能找到用户,并且密码正确
    if user is not None:
        #user_auth表中的字段
        if user.is_active:
            #该账号为管理员账号
            if user.is_superuser:
                login(request, user)
                request.session['usertype'] = 'manager' #对应数据库django_session表中的session_data(加密)
                token = createJwt(user.username,user.id)
                return JsonResponse({"ret":2,'token':token})
            else:
                login(request, user)
                token = createJwt(user.username,user.id)
                return JsonResponse({"ret":0,'token':token})
        else:
            return JsonResponse({"ret":1, "msg":"用户已被禁用"})
    else:
        return JsonResponse({'ret':3,'msg':'用户不存在'})

#登出
def signout(request):
    logout(request)
    return JsonResponse({"ret":0})

添加路由

manager/urls.py

from manager import sign_in_out
urlpatterns = [
    path('signin',sign_in_out.login),
    path('signout',sign_in_out.logout)]

我们在处理用户请求前,应该判断发出请求的用户是否登录了。对于请求消息的合法性验证,通常有两种方案 : session 和 cookie

session

session 就是 会话 的意思

session 的原理如下:

  • 服务端在数据库中保存一张session表,这张表记录了一次用户登录的相关信息。具体记录的信息,不同的系统各有差异,通常会记录该用户的ID、姓名、登录名之类的

Django中该表的名字就叫 django_session ,如下图所示

sessionId通常就是一串字符串来标记一个session的,而session 对应的数据在这里是加密的

通过上面这张表,服务端可以根据session号(sessionId) 查到 session 的信息数据。

在用户登录成功后,服务端就在数据库session表中 创建一条记录,记录这次会话,也就是创建一个新的 sessionId 插入到该表中,同时写入一些该 session 对应的数据到记录的数据字段中,比如登录用户的信息。然后在该登录请求的http响应消息中的 Set-Cookie 里填入sessionId数据。

根据http协议,这个Set-Cookie字段的意思就是 要求前端将其中的数据存入cookie中。并且随后访问该服务端的时候,在HTTP请求消息中必须带上这些cookie 数据。

cookie 通常就是存储在客户端浏览器的一些数据,服务器可以通过http响应消息要求浏览器存储一些数据。

以后每次访问同一个网站的服务,必须在HTTP请求中再带上这些cookie里的数据。

cookie数据由多个键值对组成,比如:

sessionid=xxxx
username=xxxx
favorite=phone_laptop_watch
  • 该用户的后续操作,触发的HTTP请求,都会在请求头的Cookie字段带上前面说的sessionid 。

服务端接收到该请求后,只需要到 session 表中查看是否有该 sessionid 对应的记录,这样就可以判断这个请求是否是前面已经登录的用户发出的。如果不是,就可以拒绝服务,重定向http请求到登录页面让用户登录。

使用session验证客户端请求

验证请求的cookie里是否有sessionid ,并检查session表,看看是否存在session_key为该sessionid的一条记录,该记录的数据字典里面是否包含了usertype 为 manager 的数据

manager/action.py

def dispatcher(request):
    #根据session判断用户是否为登录的管理员
    if 'usertype' not in request.session:
        return JsonResponse({'ret':302,'msg':'未登录'},status=302)
    if request.session['usertype'] != "manager":
        return JsonResponse({'ret':302,'msg':'非管理员'},status=302)
    #将请求参数统一放入request的params属性中,方便后续处理

    #GET请求参数在request对象的GET属性中
    if request.method == 'GET':
        request.params = request.GET

    elif request.method == ['POST','PUT','DELETE']:
        request.params = json.loads(request.body)

    action = request.params['action']
    if action == 'list_customer':
        return listCustomer(request)  #处理函数
    elif action == 'add_customer':
        return addCustomer(request)
    elif action == 'modify_customer':
        return modifyCustomer(request)
    elif action == 'delete_customer':
        return deleteCustomer(request)
    else:
        return JsonResponse({'ret':1, 'msg':'不支持该类型http请求'})  #转换成json形式

JWT(Json Web Token)

用户登录,服务端给用户返回一个token(服务端不保存),以后用户再来访问,需要携带token,服务端获取token后,再做token的校验

相较于传统的token,它无需在服务器保存token

实现过程

  1. 用户提交用户名和密码给服务器。如果登录成功,使用jwt创建一个token,并给用户返回。(http://jwt.io)

63skRA.png

  1. 以后用户再来访问的时候,需要携带token,后端需要对token进行校验
  • 获取token
  • 对token进行分割,分割成三段字符串
  • 对第二段进行base64解密,并获取payload信息,检测token是否超时
  • 把第一二段拼接,再次执行生成token相同的加密操作,将第三段字符串进行base64解密,将两个token进行比较,与如果相等,证明token未被修改(认证通过)

应用

python 中的 pyjwt 库实现了jwt算法,安装:

pip install pyjwt
实现

生成token

import jwt
import datetime
def createJwt(username,userId):
    salt = settings.SECRET_KEY #随机字符串
    #构造Header
    headers = {
        'typ':'jwt',
        'alg':'HS256'
    }
    #构造payload
    payload = {
        'user_id':userId,
        'username':username,
        'exp':datetime.datetime.utcnow() + datetime.timedelta(minutes=60) #超时时间
    }
    token = jwt.encode(payload=payload,key=salt,algorithm="HS256",headers=headers)
    return token

校验token

def checkToken(request):
    flag = 0
    try:
        token = request.META['HTTP_COOKIE']    #获取http请求头,请求将token放入cookie字段中
    except:
        return JsonResponse({'ret':1,'msg':'无token信息'})
    ''' 1.切割
        2.解密
        3.验证第三段的合法性'''
    # print("token1",token)
    tokenList = token.split('=')
    token = tokenList.pop()
    salt = settings.SECRET_KEY
    # print("token",token)
    verifiedPayload = None
    try:
        verifiedPayload = jwt.decode(token, salt, algorithms="HS256")
        # print("verified",verifiedPayload)
    except exceptions.ExpiredSignatureError:
        flag = 1   #token已失效
        return {'flag':flag}
    except jwt.DecodeError:
        flag = 2   #token认证失败
        return {'flag':flag}

    except jwt.InvalidTokenError:
        flag = 3   #非法的token
        return {'flag':flag}

    if not verifiedPayload:  #校验失败
        flag = 4
        return {'flag':flag}

    return {'flag':flag,'payload':verifiedPayload}

关闭Django跨域

基于前后端分离的框架,前端向Django发送http请求前,需要关闭Django跨域,否则会出错。

安装

pip install django-cors-headers

settings.py

INSTALLED_APPS = [
    'corsheaders'] 

MIDDLEWARE_CLASSES = (
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware', # 注意顺序
)
#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
    '*'
)

CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
)

CORS_ALLOW_HEADERS = (
    'XMLHttpRequest',
    'X_FILENAME',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'Pragma',
)

   转载规则


《Django开发》 fightingtree 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录