python web开发篇之JWT原理、构成及逻辑实现

原文链接:https://blog.csdn.net/weixin_45912307/article/details/110456550

1. 后端接口分析–登录功能

1. 请求fang
1.1 请求方式: post
1.2 请求路径:django_admin/authorization
1.3 请求参数:

{
    "usernname":"jsonLiu",
    "user_id":8100,
    "token":"afagagaf856123054AFAGHAHGV"
}

1.4 响应结果
在这里插入图片描述

2. Json web token (JWT)业务逻辑

2.1 用户使用用户名密码来请求服务器
2.2 服务器进行验证用户的信息
2.3 服务器通过验证发送给用户一个token
2.4 客户端存储token,并在每次请求时附送上这个token值
2.5 服务端验证token值,并返回数据

3. 后端逻辑实现

3.1 安装配置
ppip install djangorestframework-jwt
3.2 在settings.py文件中添加如下配置

import datetime

REST_FRAMEWORK = {
    # 指定认证
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}

# jwt配置
JWT_AUTH = {
    # 指定有效期
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
    # 指定返回结果方法
    'JWT_RESPONSE_PAYLOAD_HANDLER':
    	'django_admin.utils.jwt_response_payload_handler',
}

3.3 在登录子应用django_admind的urls.py中添加路由信息

from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    url(r'^authorizations/$', obtain_jwt_token),
]

3.4 将子应用添加到项目路由urls.py文件中

from django.conf.urls import url
from django.urls import include
urlpatterns = [
 url(r'^django_admin/',include('django_admin.urls'))
]

3.5 在子应用下新建utils.py文件, 重写jwt_response_payload_handler方法(原生方法只返回token,不符合需求)

def jwt_response_payload_handler(token, user=None, request=None):
    """
    自定义jwt认证成功返回数据
    """
    return {
        'token': token,
        'id': user.id,
        'username': user.username
    }

3.6 在django_admin/utils/authenticate.py中重写authenticate的方法(让管理员用户才能登录admin后台)

from django.contrib.auth.backends import ModelBackend
from users.models import User


class djangoModelBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        if request is None:
            # 后台登录
            try:
                # is_superuser判断是否是超级管理员用户
                user = User.objects.get(username=username, superuser=True)
            except:
                user = None
            # 判断密码
            if user is not None and user.check_password(password):
                return user

        else:
            # 前台登录
            # 变量username的值,可以是用户名,也可以是手机号,需要判断,再查询
            try:
                # if re.match(r'^1[3-9]\d{9}$', username):
                #     user = User.objects.get(mobile=username)
                # else:
                #     user = User.objects.get(username=username)
                user = User.objects.get(username=username)
            except:
                # 如果未查到数据,则返回None,用于后续判断
                try:
                    user = User.objects.get(mobile=username)
                except:
                    return None
                    # return None

            # 判断密码
            if user.check_password(password):
                return user
            else:
                return None

4. jwt原理及构成

4.1 session认证机制
在这里插入图片描述
4.2 token认证机制流程形式
在这里插入图片描述
4.3 jwt组成

  • (header)头部承载两部分信息: base64
    • 声明token类型,这里是jwt
    • 声明加密的算法 通常直接使用 HMAC SHA256
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
  • payload(载荷)就是存放有效信息的地方 base64
    • iss: jwt签发者
    • exp: jwt的过期时间
    • iat: jwt的签发时间
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
  • signature(签证信息) sha256
    • header (base64后的)
    • payload (base64后的)
    • secret
      base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加secret组合加密,然后就构成了jwt的第三部分
// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload)

var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
  • signature(签名)
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
  • jwt最终组成(将header、payload、signature用. 进行连接)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

4.4 jwt工作总流程
在这里插入图片描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页