杂七杂八之基于JSON Web Token (JWT) 进行API认证和鉴权(Java版)
杂七杂八之基于JSON Web Token (JWT) 进行API认证和鉴权(Java版)
在现代Web应用和API开发中,JSON Web Token (JWT) 是一种广泛使用的认证和鉴权机制。JWT不仅简化了认证流程,还提供了安全的令牌传递方式,使得跨域认证变得更加容易。本文将详细介绍如何使用JWT进行API认证和鉴权,并提供一个简单的示例。
什么是JSON Web Token (JWT)?
JSON Web Token (JWT) 是一种开放标准 (RFC 7519),用于在网络应用之间安全地传输信息。JWT是一个紧凑的、URL安全的字符串,可以包含声明(claims),这些声明用于传输关于实体(通常是用户)的信息。JWT通常由三部分组成:
- Header:包含令牌的类型(即JWT)和所使用的签名算法(如HMAC SHA256或RSA)。
- Payload:包含声明,即关于实体的信息。声明可以分为注册声明、公有声明和私有声明。
- Signature:用于验证消息的完整性和确保消息来自可信方。
一个典型的JWT可能如下所示:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT的工作原理
- 生成JWT:
● 用户通过用户名和密码进行登录。
● 服务器验证用户身份后,生成一个JWT。
● 服务器将JWT返回给客户端。 - 使用JWT:
● 客户端在每次请求中将JWT放在请求头的Authorization字段中,格式为Bearer 。
● 服务器接收到请求后,解析JWT并验证其签名。
● 服务器根据JWT中的信息进行鉴权,决定是否允许请求。
使用JWT进行API认证和鉴权
第一步:我们首先使用maven引入相关包
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>
第二步:我们编写类AuthService,目的是生成对应的token信息
/*** @author Sam Zhang* @date 2024-11-09 08:54:54* @since 0.0.1* 注释:登录用户生成token信息*/
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import java.util.Date;public class AuthService {private static final String SECRET_KEY = "analysis_service";private static final long EXPIRATION_TIME = 86400000; // 1 day in milliseconds:86400000/**** @author Sam Zhang* @date 2024/11/9 9:00* @Description: 验证用户名密码,并且进行token生成* @param: username:目前写死用户名密码* @param: password:目前写死用户名密码* @return * @return java.lang.String*/public String login(String username, String password) {// 这里验证用户名和密码// 验证成功后生成Tokenif(username.equals("authUser") && password.equals("authPasswd")){return generateToken(username);}else{return "username or password is incorrect";}}/*** @author Sam Zhang* @date 2024/11/9 9:04* @Description: 生成token* @param: username:通过用户名生成token* @return * @return java.lang.String*/private String generateToken(String username) {return Jwts.builder().setSubject(username).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)).signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();}
}
第三步:我们编写类TokenService,对生成的token进行后续校验使用
/*** @author Sam Zhang* @date 2024-11-09 09:03:49* @since 0.0.1* 注释:验证Token的合法性*/
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;public class TokenService {private static final String SECRET_KEY = "analysis_service";/**** @author Sam Zhang* @date 2024/11/9 9:16* @Description: 检查token是否还有效* @param: token:获取的token值* @return * @return boolean*/public boolean isTokenValid(String token) {if (token != null && token.startsWith("Bearer:[\"")) {token = token.substring(9,token.length()-2);try {// 解析Token并验证Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);return true; // 验证通过} catch (Exception e) {return false; // 验证失败}}else {return false; // 验证失败}}public String getUsernameFromToken(String token) {Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();return claims.getSubject();}
}
第四步:对外暴露接口,我们使用SpringBoot框架进行实现,在controller层新建类AuthService,我们提供如下对外接口
import cn.hutool.json.JSONObject;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;/*** @author Sam Zhang* @date 2024-11-09 09:18:33* @since 0.0.1* 注释:鉴权相关服务*/@RestController
public class AuthService {@AutowiredGenerateAuthlmpl generateAuthlmpl;@ApiOperation(value = "使用用户名密码进行鉴权以获得token信息", notes = "使用用户名密码进行鉴权以获得token信息")@ApiImplicitParams({@ApiImplicitParam(name = "jsonObject", value = "后续接口调用都需要鉴权",required=true,paramType = "body")})@PostMapping(value = "/gettoken",produces = "application/json;charset=UTF-8")public JSONObject getToken(@RequestBody JSONObject jsonObject) {JSONObject result = new JSONObject();CheckRequestBody checkRequestBody = new CheckRequestBody();boolean b = checkRequestBody.checkGetToken(jsonObject);if(!b){result.append("result",GETTOKENMISSBODY);result.append("msg","请检查请求body是否缺少对应字段");return result;}//检查没有问题以后,获取对应的字段信息String username = jsonObject.getStr("username");String password = jsonObject.getStr("password");//数据处理后传给后端进行token生成LoginInfos loginInfos = new LoginInfos();loginInfos.setUsername(username);loginInfos.setPassword(password);result = generateAuthlmpl.generateAuth(loginInfos);//返回结果return result;}}
第五步:当我们需要获取对应token以后,我们需要对后续的接口进行接口验证,我们其他接口的示例如下
import cn.hutool.json.JSONObject;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** @author Sam Zhang(27988)* @date 2024-11-06 10:51:40* @since 0.0.1* 注释:文件处理相关接口*/@RestController
public class DealWithFiles {private final Logger log = LoggerFactory.getLogger(this.getClass());ExecutorService executorService = Executors.newFixedThreadPool(1);@AutowiredDownLoadLogslmpl downLoadLogslmpl;@ApiOperation(value = "下载日志并且进行分析", notes = "下载日志并且进行分析")@ApiImplicitParams({@ApiImplicitParam(name = "Authorization", value = "获取的token信息",required=true,paramType = "header"),@ApiImplicitParam(name = "jsonObject", value = "分析接口请求内容",required=true,paramType = "body")})@PostMapping(value = "/analysis",produces = "application/json;charset=UTF-8")public JSONObject analysisLogs(@RequestHeader("Authorization") String authHeader, @RequestBody JSONObject jsonObject) {JSONObject result = new JSONObject();//校验消息头TokenService tokenService = new TokenService();boolean tokenValid = tokenService.isTokenValid(authHeader);if(!tokenValid){result.append("result",UNAUTH);result.append("msg","鉴权校验失败,请检查");return result;}//后续代码省略}
}
接口验证
鉴权接口
- 接口名称:/gettoken
- 接口方法:post
- 消息头:Content-Type:application/json;charset=UTF-8
- 编码:UTF-8
- 请求消息体格式:Json格式
{"username": "XXX","password": "XXX"
}
● username:鉴权用户名,当前只有这么1个。
● password:鉴权密码,当前只有这么1个。
6. 响应消息体格式:Json格式
{"msg": ["token生成成功"],"token": ["eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhdXRoVXNlciIsImlhdCI6MTczMTMwMzMzMywiZXhwIjoxNzMxMzg5NzMzfQ.DlxEJjQpITT_y_5W_lZS67hVJ1PTHQdMI7De1mQKH04"],"result": [100],"username": ["XXX"]
}
● msg:返回的消息格式。
● token:返回的token信息。
● result:返回的结果码,100表示请求成功。
● username:对应用户鉴权。
需要被验证接口
- 接口名称:/analysis
- 接口方法:post
- 消息头:
● Content-Type:application/json;charset=UTF-8
● Authorization: Bearer:[“token信息”],样例:Authorization: Bearer:[“eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhdXRoVXNlciIsImlhdCI6MTczMTMwMzMzMywiZXhwIjoxNzMxMzg5NzMzfQ.DlxEJjQpITT_y_5W_lZS67hVJ1PTHQdMI7De1mQKH04”]
● 消息头如果验证不通过,则会有如下结果返回
{"msg":["鉴权校验失败,请检查"],"result":[104]
}
至此,我们基于JSON Web Token (JWT)的鉴权完成。
相关文章:

杂七杂八之基于JSON Web Token (JWT) 进行API认证和鉴权(Java版)
杂七杂八之基于JSON Web Token (JWT) 进行API认证和鉴权(Java版) 在现代Web应用和API开发中,JSON Web Token (JWT) 是一种广泛使用的认证和鉴权机制。JWT不仅简化了认证流程,还提供了安全的令牌传递方式,使得跨域认证…...

建设展示型网站企业渠道用户递达
展示型网站的主要作用便是作为企业线上门户平台、信息承载形式、拓客咨询窗口、服务/产品宣传订购、其它内容/个人形式呈现等,网站发展多年,现在依然是企业线上发展的主要工具之一且有建设的必要性。 谈及整体价格,自制、定制开发、SAAS系统…...

如何通过AB测试找到最适合的Yandex广告内容
想要在Yandex上找到最能吸引目标受众的广告内容,A/B测试是一个不可或缺的步骤。通过对比不同版本的广告,我们可以发现哪些元素最能引起用户的共鸣。首先,设计两个或多个广告版本,确保每个版本在标题、文案、图片等关键元素上有所不…...

AI写作(四)预训练语言模型:开启 AI 写作新时代(4/10)
一、预训练语言模型概述 预训练语言模型在自然语言处理领域占据着至关重要的地位。它以其卓越的语言理解和生成能力,成为众多自然语言处理任务的关键工具。 预训练语言模型的发展历程丰富而曲折。从早期的神经网络语言模型开始,逐渐发展到如今的大规…...

解决Anaconda出现CondaHTTPError: HTTP 000 CONNECTION FAILED for url
解决Anaconda出现CondaHTTPError: HTTP 000 CONNECTION FAILED for url 第一类情况 在anaconda创建新环境时,使用如下代码 conda create -n charts python3.7 错误原因: 默认镜像源访问速度过慢,会导致超时从而导致更新和下载失败。 解决方…...

员工绩效统计出现很多小数点,处理方法大全
1.直接通过数据库修改数据类型 譬如采用DECIMAL类型 2.float 降低小数点位数 3.php 采用round函数...

【启明智显分享】5G CPE为什么适合应用在连锁店中?
连锁门店需要5G CPE来满足其日益增长的网络需求,提升整体运营效率和竞争力。那么为什么5G CPE适合连锁店应用呢,小编为此做了整理,主要是基于以下几个方面的原因: 一、高效稳定的网络连接 1、高速数据传输: 5G CPE能…...

十大经典排序算法-希尔排序与归并排序
1、希尔排序 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎已经排好序的数据操作时,效率高&…...

gitlab和jenkins连接
一:jenkins 配置 安装gitlab插件 生成密钥 id_rsa 要上传到jenkins,id_rsa.pub要上传到gitlab cat /root/.ssh/id_rsa 复制查看的内容 可以看到已经成功创建出来了对于gitlab的认证凭据 二:配置gitlab cat /root/.ssh/id_rsa.pub 复制查…...

Qt Event事件系统小探2
目录 事件过滤器 来看一个例子 拖放事件和拖放操作 Qt官方文档给出的说明 拖放 拖放类 配置 拖动 放置 覆盖建议的操作 子类化复杂窗口小部件 拖放操作 添加新的拖放类型 放置操作 放置矩形 剪贴板 其他函数的介绍 事件过滤器 我们知道,有的时候想…...

[2024最新] java八股文实用版(附带原理)---java集合篇
介绍一下常见的list实现类? ArrayList 线程不安全,内部是通过数组实现的,继承了AbstractList,实现了List,适合随机查找和遍历,不适合插入和删除。排列有序,可重复,当容量不够的时候…...

pytorch tensor在CPU和GPU之间转换,numpy之间的转换
# input input.cpu().numpy() input input.cpu().detach().numpy() # 有gradCPU tensor转GPU tensor: cpu_imgs.cuda()GPU tensor 转CPU tensor: gpu_imgs.cpu()numpy转为CPU tensor: torch.from_numpy( imgs )4.CPU tensor转为numpy数…...

【电压分层控制】光储三相并网下垂控制,直流微电网协调母线电压分层控制
摘要 本文研究了一种基于电压分层控制的光伏与储能系统并网控制策略。通过下垂控制和分层控制方法实现直流微电网的协调运行,提高系统动态响应和稳态性能。仿真结果表明,该控制策略能够在不同工况下有效稳定母线电压,并实现负载功率合理分配…...

【CSS】absolute定位的默认位置
position: absolute; 属性会使元素脱离正常的文档流,并相对于最近的非 static 定位祖先元素进行定位。如果没有这样的祖先元素,则相对于初始包含块(通常是视口)进行定位。 但是当top和left没有指定具体值时,元素的在上…...

遗传算法与深度学习实战——利用进化计算优化深度学习模型
遗传算法与深度学习实战——利用进化计算优化深度学习模型 0. 前言1. 利用进化计算优化深度学习模型2. 利用进化策略优化深度学习模型3. 利用差分计算优化深度学习模型相关链接 0. 前言 我们已经学习了使用进化策略 (Evolutionary Strategies, ES) 和差分进化 (Differential E…...

计算机视觉 ---图像读取与显示(OpenCV与Matplotlib)
前言 本文分别介绍了使用 OpenCV 和 Matplotlib 进行图像读取与显示的方法,如 cv2.imread ()、cv2.imshow ()、plt.imread ()、plt.imshow () 等,并提及了使用 OpenCV 时的注意事项。 OpenCV与Matplotlib图像读取与显示的差异 图像读取: Op…...

XML Schema 字符串数据类型
XML Schema 字符串数据类型 1. 概述 XML Schema 是一种用于定义 XML 文档结构和内容的语言。它提供了一种强大的机制来描述 XML 数据的类型、结构和约束。在 XML Schema 中,字符串数据类型是一种基本数据类型,用于表示文本数据。 2. 字符串数据类型 …...

Spring Boot 读取 yml 并映射至实体
application-base.yml app:# 附件存储路径upload-attachments: /data/attachments/# 报告导出详情 url - 前端score-detail-url: ${app.host.web}/#/process/start?processNo{}# api 文件下载 urlfile-download-url: ${app.host.web}/prod-api/sys_file_info/download/{}?fu…...

/// ts中的三斜线指令 | 前端
第一次看到注意到这行代码,不知道的还以为是注释呢,查了资料才知道这是typescript中的三斜线指令,那有什么作用呢? 1. 这行代码是TypeScript中的一个三斜线指令(Triple-Slash Directive),用于…...

什么岗位需要学习 OpenGL ES ?说说 3.X 的新特性
什么是 OpenGL ES OpenGL ES 是一种为嵌入式系统和移动设备设计的3D图形API(应用程序编程接口)。它是标准 OpenGL 3D 图形库的一个子集,专门为资源受限的环境(如手机、平板电脑、游戏机和其他便携式设备)进行了优化。 由于其在移动设备上的广泛适用性,OpenGL ES是学习移…...

【插件】多断言 插件pytest-assume
背景 assert 断言一旦失败,后续的断言不能被执行 有个插件,pytest-assume的插件,可以提供多断言的方式 安装 pip3 install pytest-assume用法 pytest.assume(表达式,f’提示message’) pytest.assume(表达式,f‘提示message’) pytest.ass…...

ctfshow DSBCTF web部分wp
ctfshow 单身杯 web部分wp web 签到好玩的PHP 源码: <?php error_reporting(0); highlight_file(__FILE__);class ctfshow {private $d ;private $s ;private $b ;private $ctf ;public function __destruct() {$this->d (string)$this->d;$this…...

三维点云 和模型转换的问题
随着科技的发展,三维激光扫描采集的点云数据作为一种新型的数据形式,在多个领域中都展现出了其强大的应用价值。那么,什么是点云数据?它是如何生成的?又能为我们的生活和工作带来哪些便利呢? 1.…...

黑马智数Day7
获取行车管理计费规则列表 封装接口 export function getRuleListAPI(params) {return request({url: parking/rule/list,params}) } 获取并渲染数据 import { getRuleListAPI } from /apis/carmounted() {this.getRuleList() }methods: {// 获取规则列表async getRuleList(…...

虚拟机安装Ubuntu 24.04服务器版(命令行版)
这个是专门用于服务器使用的,没有GUI,常用软件安装,见 虚拟机安装Ubuntu 24.04及其常用软件(2024.7)_ubuntu24.04-CSDN博客https://blog.csdn.net/weixin_42173947/article/details/140335522这里只记录独特的安装步骤 1 下载Ubuntu 24.04安…...

.net core开发windows程序在国产麒麟操作系统中运行
.net core自从3.1版本号后,完全是一个独立的开源的多平台开发组件,目前国产化是趋势,不少项目需要开发国产如Kylin操作系统中运行的程序,无论是Web程序还是桌面程序,都有这样的需求。 首先,可明确的的.net…...

【LinuxC编程】06 - 守护进程,线程
进程组和会话 概念和特性 进程组,也称之为作业。BSD于1980年前后向Unix中增加的一个新特性。代表一个或多个进程的集合。每个进程都属于一个进程组。在waitpid函数和kill函数的参数中都曾使用到。操作系统设计的进程组的概念,是为了简化对多个进程的管…...

<websocket><PLC>使用js和html实现webscoket,与PLC进行socket通讯的实例
前言 本文是为了实现从网页端通过websocket与PLC端的socket进行数据通讯。 环境配置 系统:windows 平台:visual studio code 语言:javascript、html、PLC 库:node.js 概述 本文的目的是通过网页端与PLC进行socket通讯,但web端一般并不是直接使用socket,而是websocket,…...

nginx部署H5端程序与PC端进行区分及代理多个项目及H5内页面刷新出现404问题。
在项目中会碰见需要在nginx代理多个项目,如果在加上uniapp开发的H5端的项目,你还要在nginx中区分PC端和手机H5端,这就会让人很头大!网上大部分的资料都是采用在nginx的conf配置文件中添加区分pc和手机端的变量例如:set…...

blenderFds代码解读
文章目录 一. 介绍1. FDS(Fire Dynamics Simulator)2. BlenderFDS 二. 下载代码三. 开发环境配置四. 代码解读1. blender python特有语法2. 代码结构2.1 变量名解释2.2 bl文件夹operators文件夹ui其他文件 2.2 lang文件夹bf_sceneON_GEOMON_MESHON_MOVEO…...