ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

DRF组件之JWT认证模块

2022-05-23 14:01:24  阅读:153  来源: 互联网

标签:加密 jwt base64 JWT 认证 token 组件 DRF


JWT认证简介

jwt:json web token,是一种前后端的登录认证方式,

它分token的签发和认证,签发的意思是用户登录成功,生成三段式的token串;

认证指的是用户访问某个带有用户登录权限的接口,需要携带token串过来,完成认证。
三段式分为头、荷载和签名。

认证通过头和荷载,通过加密得到签名,然后比较两个签名是否一样,一样就通过不一样就不通过。

JWT的构成

JWT就是一段字符串,由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串。

JWT三段式:头.体.签名 (head.payload.sign)

第一部分我们称它为头部(header),第二部分我们称其为载荷(payload),第三部分是签证(signature).

JWT的原理

1)jwt分三段式:头.体.签名 (head.payload.sign)
2)头和体是可逆加密,让服务器可以反解出user对象;签名是不可逆加密,保证整个token的安全性的
3)头体签名三部分,都是采用json格式的字符串,进行加密,可逆加密一般采用base64算法,不可逆加密一般采用hash(md5)算法
4)头中的内容是基本信息:公司信息、项目组信息、token采用的加密方式信息 { "company": "公司信息", ... }
5)体中的内容是关键信息:用户主键、用户名、签发时客户端信息(设备号、地址)、过期时间 { "user_id": 1, ... }
6)签名中的内容时安全信息:头的加密结果 + 体的加密结果 + 服务器不对外公开的安全码 进行md5加密 { "head": "头的加密字符串", "payload": "体的加密字符串", "secret_key": "安全码" }

JWT认证算法:签发+校验

签发

根据登录请求提交来的 账号 + 密码 + 设备信息 签发 token

1)用基本信息存储json字典,采用base64算法加密得到 头字符串
2)用关键信息存储json字典,采用base64算法加密得到 体字符串
3)用头、体加密字符串再加安全码信息存储json字典,采用hash md5算法加密得到 签名字符串 账号密码就能根据User表得到user对象,形成的三段字符串用 . 拼接成token返回给前台

校验

根据客户端带token的请求 反解出 user 对象

1)将token按 . 拆分为三段字符串,第一段 头加密字符串 一般不需要做任何处理
2)第二段 体加密字符串,要反解出用户主键,通过主键从User表中就能得到登录用户,
过期时间和设备信息都是安全信息,确保token没过期,且时同一设备来的
3)再用 第一段 + 第二段 + 服务器安全码 不可逆md5加密,与第三段签名字符串进行碰撞校验,
通过后才能代表第二段校验得到的user对象就是合法的登录用户

drf项目的jwt认证开发流程(重点)

1)用账号密码访问登录接口,登录接口逻辑中调用 签发token 算法,得到token,返回给客户端,客户端自己存到cookies中

2)校验token的算法应该写在认证类中(在认证类中调用),
全局配置给认证组件,所有视图类请求,都会进行认证校验,
所以请求带了token,就会反解出user对象,在视图类中用request.user就能访问登录的用户 注:登录接口需要做 认证 + 权限 两个局部禁用

base64编码解码

import base64
import json
dic_info={
  "sub": "1234567890",
  "name": "lqz",
  "admin": True
}
byte_info=json.dumps(dic_info).encode('utf-8')
# base64编码
base64_str=base64.b64encode(byte_info)
print(base64_str)
# base64解码
base64_str='eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogImxxeiIsICJhZG1pbiI6IHRydWV9'
str_url = base64.b64decode(base64_str).decode("utf-8")
print(str_url)

JWT的安装

pip install djangorestframework-jwt

JWT的简单使用

新建一个项目,在模型类中继承 AbstractUser 表

# models.py

from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    phone = models.CharField(max_length=11)
    icon = models.ImageField(upload_to='icon')

在配置文件中配置

# settings.py

AUTH_USER_MODEL = 'api.User'  # '应用名.表名'
# 一定要在执行数据库迁移命令前配置上面这条配置信息,否则会创建django的au_user表 

执行数据库迁移命令并创建超级用户

# Terminal终端

# 分别执行下面两条数据库迁移命令
python manage.py makemigrations
python manage.py migrate

# 创建超级用户
python manage.py createsuperuser

路由配置

# urls.py

from django.urls import path,re_path
from rest_framework_jwt.views import ObtainJSONWebToken,RefreshJSONWebToken,VerifyJSONWebToken
from rest_framework_jwt.views import obtain_jwt_token
''' 基类:JSONWebTokenAPIView继承了APIView ObtainJSONWebToken,RefreshJSONWebToken,VerifyJSONWebToken都继承了JSONWebTokenAPIView obtain_jwt_token = ObtainJSONWebToken.as_view() refresh_jwt_token = RefreshJSONWebToken.as_view() verify_jwt_token = VerifyJSONWebToken.as_view() '''

urlpatterns = [ # path('login/', ObtainJSONWebToken.as_view()), path('login/', obtain_jwt_token), # 本质跟上面的那条路由相同 ]

postman测试

1.postman中向http://127.0.0.1:8000/api/login/发送post请求,
  请求体中携带用户名和密码,即可看到生成的token

视图类书写测试接口

from rest_framework.views import APIView
from rest_framework.response import Response

from rest_framework_jwt.authentication import JSONWebTokenAuthentication

class UserView(APIView):
    # 局部配置上JWT认证
    authentication_classes = [JSONWebTokenAuthentication,]
    def get(self,request):
        return Response('ok')

在postman中访问http://127.0.0.1:8000/api/user/测试

1. 用get请求访问http://127.0.0.1:8000/api/user/

2.在headers中加参数Authorization,对应的value值:JWT+空格+token值

 

 只要Authorization对应的value值JWT后的token值错误,就会直接校验不通过

 这样,我们就通过JWT完成了一个简单的登录校验功能,但是却存在很大的弊端

如果我们在Authorization对应的value值中不加上JWT,
JWT就会默认不对该功能进行认证校验,所以我们需要自己写一个认证类

 

标签:加密,jwt,base64,JWT,认证,token,组件,DRF
来源: https://www.cnblogs.com/yesirya/p/16300939.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有