166.JWT简介与Django中使用JWT

news2024/11/18 11:30:03

1. JWT

1.1 JWT概述

在这里插入图片描述

基于django-rest-framework的登陆认证方式常用的大体可分为四种:

  1. BasicAuthentication:账号密码登陆验证
  2. SessionAuthentication:基于session机制会话验证
  3. TokenAuthentication: 基于令牌的验证
  4. JSONWebTokenAuthentication:基于Json-Web-Token的验证(对第三种进行封装,最常用的方式)
    我们前面演示的就是第1,2种认证方式,而实际项目中,最常用的就是JWT的方式
    JWT具有以下优点:
  5. 签名的方式验证用户信息,安全性较之一般的认证高
  6. 加密后的字符串保存于客户端浏览器中,减少服务器存储压力
  7. 签名字符串中存储了用户部分的非私密信息,能够减少服务器数据库的开销
  8. 能够不需要做任何额外工作,即可实现单点登录
    缺点:
  9. 采用对称加密,一旦被恶意用户获取到加密方法,就可以不断破解入侵获取信息
  10. 加大了服务器的计算开销
    61

1.2 JWT简介

JWT 是一个开放标准(RFC 7519),它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。

1.3 JWT 组成

在这里插入图片描述

  • header、Payload和Signature之间用 . 号连接
  • Header 头部
    头部包含了两部分,token 类型和采用的加密算法
{
 "alg": "HS256",
 "typ": "JWT"
}
  • typ : (Type)类型,指明类型是 JWT 。
  • alg : (Algorithm)算法,必须是JWS支持的算法,主要是HS256和RS256
    它会使用 base64url编码组成 JWT 结构的第一部分
  • Payload 负载
    这部分就是我们存放信息的地方了,你可以把用户 ID 等信息放在这里,JWT 规范里面对这部分有进行了比较详细的介绍,JWT 规定了7个官方字段,供选用
iss (issuer):签发人
exp (expiration time):过期时间,时间戳
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间,时间戳
iat (Issued At):签发时间,时间戳
jti (JWT ID):编号

常用的有iss、iat、exp、aud和sub
同样的,它会使用 base64url 编码组成 JWT 结构的第二部分

  • Signature 签名
    签名的作用是保证 JWT 没有被篡改过
    前面两部分都是使用 base64url 进行编码的,前端可以解开知道里面的信息。Signature 需要使用编码后的 header 和 payload 以及我们提供的一个密钥,这个密钥只有服务器才知道,不能泄露给用户,然后使用 header 中指定的签名算法(HS256)进行签名。
HMACSHA256(
 base64UrlEncode(header) + "." +
 base64UrlEncode(payload),
 secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNTY3MTU2MTA5LCJlbWFpbCI6ImFkbWluQGV4YW1wbGUuY29tIiwib3JpZ19pYXQiOjE1NjY1NTEzMDl9.VwVwdkQalKip4Cp1_8QjcqR0n_S9w3jgUJEf3oO4PoI
  • 签名的目的
    最后一步签名的过程,实际上是对头部以及负载内容进行签名,防止内容被篡改。如果有人对头部以及负载的内容解码之后进行修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的。如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的。

2. JWT的使用方式

2.1 JWT流程

客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。

此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息 Authorization 字段里面。
在这里插入图片描述

  1. 首先,前端通过Web表单将自己的用户名和密码发送到后端的接口。这一过程一般是一个HTTP POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。
  2. 后端核对用户名和密码成功后,将用户的id等其他信息作为JWTPayload(负载),将其与头部分别进行Base64编码拼接后签名,形成一个JWT。形成的JWT就是一个形同lll.zzz.xxx的字符串。
  3. 后端将JWT字符串作为登录成功的返回结果返回给前端。前端可以将返回的结果保存在localStorage或sessionStorage上,退出登录时前端删除保存的JWT即可。
  4. 前端在每次请求时将JWT放入HTTP Header中的Authorization位。(解决XSS和XSRF问题)
  5. 后端检查是否存在,如存在验证JWT的有效性。例如,检查签名是否正确;检查Token是否过期;检查Token的接收方是否是自己(可选)。

2.2 JWT 的几个特点

  1. JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。
  2. JWT 不加密的情况下,不能将秘密数据写入 JWT。
  3. JWT 不仅可以用于认证,也可以用于交换信息。有效使用JWT,可以降低服务器查询数据库的次数。
  4. JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。
  5. JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
    为了减6. 少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用
    HTTPS 协议传输。

3.项目中应用JWT

3.1 安装JWT

pip install djangorestframework-jwt==1.11.0

3.2 配置settings

REST_FRAMEWORK = {
    # 默认的验证是按照验证列表 从上到下 的验证
    'DEFAULT_AUTHENTICATION_CLASSES': (
    # 配置JWT认证
    'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    # 配置session_id认证
    'rest_framework.authentication.SessionAuthentication',
    # 配置默认的认证方式 base:账号密码验证
    'rest_framework.authentication.BasicAuthentication',
   )
}
import datetime
JWT_AUTH = {
    # 允许刷新token
    'JWT_ALLOW_REFRESH': True,
    # 每次刷新后,token的有效时间
    'JWT_EXPIRATION_DELTA':datetime.timedelta(days=1),
    # 生成 token 后,最大的有效时间:在有效期内通过刷新可以保持token有效;超过这个时间后,token失效,刷新也不起作用
    'JWT_REFRESH_EXPIRATION_DELTA':datetime.timedelta(days=30),
}

在这里插入图片描述

3.3 URLS

在根路由或子应用项目下配置JWT登录的url路由,本问配置在根urls下:
根路由

from django.contrib import admin
from django.urls import path,include
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
    path('api-token-auth/', obtain_jwt_token),
    path('admin/', admin.site.urls),
    path('',include('rest_app.urls')),
    path('api-auth/',include('rest_framework.urls')),
]

3.4 登录JWT,获取token

#url参数提交
curl http://127.0.0.1:8000/api-token-auth/ -i -X POST -d "username=admin&password=admin"
#json格式提交
curl http://127.0.0.1:8000/api-token-auth/ -i -X POST -H "Content-Type:application/json" -d {\"username\":\"admin\",\"password\":\"admin\"}

在这里插入图片描述

3.5 应用jwt操作数据

新增数据

curl http://127.0.0.1:8000/students/ -X POST -H "Content-Type:application/json" -d {\"name\":\"jwt_stu\",\"age\":24,\"sex\":1} -H "Authorization:JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNjcwNTgzNDUyLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsIm9yaWdfaWF0IjoxNjcwNDk3MDUyfQ.StD1MHJHTvLgKy6yFEpBnp9D8BP3D_WyXJsVD6ObjBo"

删除数据

curl http://127.0.0.1:8000/students/9/ -i -X DELETE -H"Authorization:JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNjcwNTgzNDUyLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsIm9yaWdfaWF0IjoxNjcwNDk3MDUyfQ.StD1MHJHTvLgKy6yFEpBnp9D8BP3D_WyXJsVD6ObjBo"

在这里插入图片描述
{“detail”:“You do not have permission to perform this action.”}
若无携带token时,会存在此报错

3.6 刷新token

添加配置url

from django.contrib import admin
from django.urls import path,include
from rest_framework_jwt.views import obtain_jwt_token,refresh_jwt_token
urlpatterns = [
    path('api-token-refresh/', refresh_jwt_token),
]

使用

curl http://127.0.0.1:8000/api-token-refresh/ -X POST -H "Content-Type:application/json" -d {\"token\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNjcwNTgzNDUyLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsIm9yaWdfaWF0IjoxNjcwNDk3MDUyfQ.StD1MHJHTvLgKy6yFEpBnp9D8BP3D_WyXJsVD6ObjBo\"}

在这里插入图片描述

3.7 认证token

有些应用中,有专门的服务器认证token,当其他其他服务器得到token之后,传递给专门的服务器认证token
urls

from django.contrib import admin
from django.urls import path,include
from rest_framework_jwt.views import obtain_jwt_token,refresh_jwt_token,verify_jwt_token
urlpatterns = [
    path('api-token-auth/', obtain_jwt_token),
    path('api-token-refresh/', refresh_jwt_token), # POST刷新JWT的token的url
    path("api-token-verify/", verify_jwt_token), # 传递给专门的服务器认证token
    path('admin/', admin.site.urls),
    path('',include('rest_app.urls')),
    path('api-auth/',include('rest_framework.urls')),
]

使用

curl http://127.0.0.1:8000/api-token-verify/ -X POST -H "Content-Type: application/json" -d {\"token\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNjcwNTgzNDUyLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsIm9yaWdfaWF0IjoxNjcwNDk3MDUyfQ.StD1MHJHTvLgKy6yFEpBnp9D8BP3D_WyXJsVD6ObjBo\"}

token正确与错误的效果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/72662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python中使用国内源头下载依赖

有关更多的Python 开发内容,可访问:《 Python Flask开发指南》 Python开发中对于项目的依赖通常是用pip install命令进行下载,默认官网下载源为国外网络,会经常出现下载超时的问题。那么如何修改下载源使得我们能快速下载资源,如下介绍两种方式设置国内下载源。 国内下载源…

西湖大学张岳老师NLP课程笔记1 Introduction

西湖大学张岳老师NLP课程笔记1 Introduction 参考资料 B站链接课程主页 《Natural Language Processing: A Machine Learning Perspective 》 csdn大佬笔记 https://blog.csdn.net/qq_45645521/category_11685799.html 文章目录西湖大学张岳老师NLP课程笔记1 Introduction1.…

常用工具:介绍一款免费开源录屏工具-captura

网上能搜到的大部分录屏工具表面打着免费的旗号,实际上下载之后不是有水印就是限制分辨率和时长,介绍一款免费无水印的开源录屏截屏工具captura。 准备工作 要使用这个工具,必须事先在电脑上安装ffmpeg工具包,安装方式见&#x…

DRV8870/A4950/AT8870(3.6A单通道刷式直流电机驱动IC)

描述 AT8870是一款刷式直流电机驱动器,适用于打印机、电器、工业设备以及其他小型机器。两个逻辑输入控制H桥驱动器,该驱动器由四个N-MOS组成,能够以高达3.6A的峰值电流双向控制电机。利用电流衰减模式,可通过对输入进行脉宽调制(…

【电源专题】案例:电池存储40天电压从3.9V掉到了3.5V是什么异常?

本案例是在我休假过程中发现的。同事反馈说客户发现我们的一批产品有概率在存储40多天后发现电池从3.9V掉到了3.5V,并且制程、软件、硬件都有差异。会有可能存在什么异常? 首先我们要了解的是大多数带电池的产品在销售给客户时都会充好电(如手机/充电宝等),但不一定是充…

极市直播预告丨阿里达摩院:兼顾速度与精度的高效目标检测框架DAMO-YOLO

|极市线上分享第106期 | 一直以来,为让大家更好地了解学界业界优秀的论文和工作,极市已邀请了超过100位技术大咖嘉宾,并完成了105期极市线上直播分享。往期分享请前往http://bbs.cvmart.net/topics/149或直接阅读原文,也欢迎各位…

初学者如何学习FPGA?一文为你讲解清楚

想学习一门技术之前,我们先会从编程语言入手。就像学习FPGA,往往是从VHDL或者Verilog开始入手学习的。 当然,任何编程语言的学习都不能一劳永逸,因为任何经验技巧都是在实践的过程中才能学到,FPGA的学习当然也不例外。…

Python爬虫实战,Request+urllib模块,批量下载爬取飙歌榜所有音乐文件

前言 今天给大家介绍的是Python爬取飙歌榜所有音频数据并保存本地,在这里给需要的小伙伴们代码,并且给出一点小心得。 首先是爬取之前应该尽可能伪装成浏览器而不被识别出来是爬虫,基本的是加请求头,但是这样的纯文 本数据爬取…

C语言实现三子棋(超详解版本)

🚀write in front🚀 📝个人主页:认真写博客的夏目浅石. 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝​ 📣系列专栏:鹏哥带我学c带我飞 💬总结:希望你看…

分布式电源接入对配电网影响的研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

springboot+easyexcel:导入excel表格

目录 前言 1.常规导入 2.读取到指定的列 3.读取全部的sheet页 4.日期、数字及其他自定义格式的转换 5.表头有多行的读取 前言 excel表格的导入与导出,可以说是业务系统里比较常见的功能了,早些时候相信很多人都是使用POI实现excel的导入与导出功能…

还有13天圣诞节,用python整个简易版的圣诞树玩一下.......

人生苦短 我用python 好像很久没发文章啦! 看一眼日历快到圣诞节了 , 现在就来用python整个圣诞树玩一下吧! 代码🎆 模块 源码、资料电子书点击此处 import turtle as t from turtle import * import random as r import time…

项目经理的需求常见分类总结

今天聊聊如何进行需求分类、需求规划和优先级排序。我们都会面临需求多,任务重,资源少的现状,在这种情况下,就需要产品人员对产品需求进行评估,找到在当前阶段最重要的功能进行开发,那么怎么来进行评估和判…

Spring整合Apollo的原理

Spring和Apollo源码涉及的类 Spring:ApplicationContextInitializer、BeanFactoryPostProcessor、BeanPostProcessor、Environment、CompositePropertySource Apollo:ApolloApplicationContextInitializer、PropertySourcesProcessor、ApolloProcessor、…

消息发布确认

描述:在消息投递的过程中可能会存在消息丢失的行为产生,生产者到交换机,交换机到队列的过程都有可能出现这个现象。所以我们要有个发布确认的操作来防止消息丢西。 确认机制方案: 配置文件配置交换机发布确认模式: p…

年终颁奖 | 建模助手年度产品经理正在评比当中!

大家好,我是建模助手。 12月来了,又到了激情总结,却发现flag倒被打脸的时刻!我就想问问在座各位:年初的定立的flag,完成得咋样了? 我们今年就有一张很优秀的成绩单:↓↓↓ 建模助手…

优优聚:学会删减菜单,帮你提升销量和转化

如今随着外卖市场的不断发展,越来越多的堂食店铺加入外卖,但是对于做外卖很多老板认为,自家堂食做得不错,那么直接把堂食的菜单上传到外卖,结果这样做的后果就是不仅累还不挣钱。下面优优聚小编就来讲一下。 1、菜单太…

IDEA 导入别人的javaweb项目进行部署

前言 我主要是进行java的springboot项目和vue项目的开发,但是架不住在这些框架兴起之前,公司内部已经是有其他的老的框架,我需要在这些老的框架进行修改和调整代码。原本我是使用的eclipse软件进行部署,也比较简单; …

了解常见的模拟器及交换机的基本配置

了解常见的模拟器及交换机的基本配置 1. 首先我们先了解常见的模拟器软件 1.Cisco Packet Tracer(简单,纯软件实现) Cisco Packet Tracer 是由Cisco公司发布的一个辅助学习工具,为学 习思科网络课程的初学者去设计、配置、排除…

chapter9——电磁兼容性能设计指南

目录1.定义2.电磁干扰理论3.电磁干扰的流程、标准和认证4.影响集成电路抗干扰性能的几个因素5.减少EMC/EMI的技术电子线路易于接收来自其他发射器的辐射信号,无论是有意或无意发射。这些电磁干扰(EMI)使得设备内毗邻的元件不能同时工作。这时…