当前位置: 首页 > news >正文

杂七杂八之基于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通常由三部分组成:

  1. Header:包含令牌的类型(即JWT)和所使用的签名算法(如HMAC SHA256或RSA)。
  2. Payload:包含声明,即关于实体的信息。声明可以分为注册声明、公有声明和私有声明。
  3. Signature:用于验证消息的完整性和确保消息来自可信方。
    一个典型的JWT可能如下所示:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT的工作原理

  1. 生成JWT:
    ● 用户通过用户名和密码进行登录。
    ● 服务器验证用户身份后,生成一个JWT。
    ● 服务器将JWT返回给客户端。
  2. 使用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;}//后续代码省略}
}

接口验证

鉴权接口

  1. 接口名称:/gettoken
  2. 接口方法:post
  3. 消息头:Content-Type:application/json;charset=UTF-8
  4. 编码:UTF-8
  5. 请求消息体格式: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:对应用户鉴权。

需要被验证接口

  1. 接口名称:/analysis
  2. 接口方法:post
  3. 消息头:
    ● 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认证和鉴权&#xff08;Java版&#xff09; 在现代Web应用和API开发中&#xff0c;JSON Web Token (JWT) 是一种广泛使用的认证和鉴权机制。JWT不仅简化了认证流程&#xff0c;还提供了安全的令牌传递方式&#xff0c;使得跨域认证…...

建设展示型网站企业渠道用户递达

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

如何通过AB测试找到最适合的Yandex广告内容

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

AI写作(四)预训练语言模型:开启 AI 写作新时代(4/10)

一、预训练语言模型概述 ​ 预训练语言模型在自然语言处理领域占据着至关重要的地位。它以其卓越的语言理解和生成能力&#xff0c;成为众多自然语言处理任务的关键工具。 预训练语言模型的发展历程丰富而曲折。从早期的神经网络语言模型开始&#xff0c;逐渐发展到如今的大规…...

解决Anaconda出现CondaHTTPError: HTTP 000 CONNECTION FAILED for url

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

员工绩效统计出现很多小数点,处理方法大全

1.直接通过数据库修改数据类型 譬如采用DECIMAL类型 2.float 降低小数点位数 3.php 采用round函数...

【启明智显分享】5G CPE为什么适合应用在连锁店中?

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

十大经典排序算法-希尔排序与归并排序

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

gitlab和jenkins连接

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

Qt Event事件系统小探2

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

[2024最新] java八股文实用版(附带原理)---java集合篇

介绍一下常见的list实现类&#xff1f; ArrayList 线程不安全&#xff0c;内部是通过数组实现的&#xff0c;继承了AbstractList&#xff0c;实现了List&#xff0c;适合随机查找和遍历&#xff0c;不适合插入和删除。排列有序&#xff0c;可重复&#xff0c;当容量不够的时候…...

pytorch tensor在CPU和GPU之间转换,numpy之间的转换

# input input.cpu().numpy() input input.cpu().detach().numpy() # 有gradCPU tensor转GPU tensor&#xff1a; cpu_imgs.cuda()GPU tensor 转CPU tensor&#xff1a; gpu_imgs.cpu()numpy转为CPU tensor&#xff1a; torch.from_numpy( imgs )4.CPU tensor转为numpy数…...

【电压分层控制】光储三相并网下垂控制,直流微电网协调母线电压分层控制

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

【CSS】absolute定位的默认位置

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

遗传算法与深度学习实战——利用进化计算优化深度学习模型

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

计算机视觉 ---图像读取与显示(OpenCV与Matplotlib)

前言 本文分别介绍了使用 OpenCV 和 Matplotlib 进行图像读取与显示的方法&#xff0c;如 cv2.imread ()、cv2.imshow ()、plt.imread ()、plt.imshow () 等&#xff0c;并提及了使用 OpenCV 时的注意事项。 OpenCV与Matplotlib图像读取与显示的差异 图像读取&#xff1a; Op…...

XML Schema 字符串数据类型

XML Schema 字符串数据类型 1. 概述 XML Schema 是一种用于定义 XML 文档结构和内容的语言。它提供了一种强大的机制来描述 XML 数据的类型、结构和约束。在 XML Schema 中&#xff0c;字符串数据类型是一种基本数据类型&#xff0c;用于表示文本数据。 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中的三斜线指令 | 前端

第一次看到注意到这行代码&#xff0c;不知道的还以为是注释呢&#xff0c;查了资料才知道这是typescript中的三斜线指令&#xff0c;那有什么作用呢&#xff1f; 1. 这行代码是TypeScript中的一个三斜线指令&#xff08;Triple-Slash Directive&#xff09;&#xff0c;用于…...

什么岗位需要学习 OpenGL ES ?说说 3.X 的新特性

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

【插件】多断言 插件pytest-assume

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

ctfshow DSBCTF web部分wp

ctfshow 单身杯 web部分wp web 签到好玩的PHP 源码&#xff1a; <?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…...

三维点云 和模型转换的问题

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

黑马智数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服务器版(命令行版)

这个是专门用于服务器使用的&#xff0c;没有GUI&#xff0c;常用软件安装&#xff0c;见 虚拟机安装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版本号后&#xff0c;完全是一个独立的开源的多平台开发组件&#xff0c;目前国产化是趋势&#xff0c;不少项目需要开发国产如Kylin操作系统中运行的程序&#xff0c;无论是Web程序还是桌面程序&#xff0c;都有这样的需求。 首先&#xff0c;可明确的的.net…...

【LinuxC编程】06 - 守护进程,线程

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

<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代理多个项目&#xff0c;如果在加上uniapp开发的H5端的项目&#xff0c;你还要在nginx中区分PC端和手机H5端&#xff0c;这就会让人很头大&#xff01;网上大部分的资料都是采用在nginx的conf配置文件中添加区分pc和手机端的变量例如&#xff1a;set…...

blenderFds代码解读

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