安全认证--JWT介绍及使用
安全认证--JWT介绍及使用
- 1.无状态登录原理
- 1.1.什么是有状态?
- 1.2.什么是无状态
- 1.3.如何实现无状态
- 1.4.JWT
- 1.4.1.简介
- 1.4.2.数据格式
- 2.编写JWT工具
- 2.1.添加JWT依赖
- 2.2.载荷对象
- 2.3.工具
- 2.4.测试
- 2.4.1.配置秘钥
- 2.4.2.测试类
1.无状态登录原理
有状态登录和无状态登录详解
1.1.什么是有状态?
有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session。
例如登录:用户登录后,我们把登录者的信息保存在服务端session中,并且给用户一个cookie值,记录对应的session。然后下次请求,用户携带cookie值来,我们就能识别到对应session,从而找到用户的信息。
缺点是什么?
- 服务端保存大量数据,增加服务端压力
- 服务端保存用户状态,无法进行水平扩展
- 客户端请求依赖服务端,多次请求必须访问同一台服务器
1.2.什么是无状态
微服务集群中的每个服务,对外提供的都是Rest风格的接口。而Rest风格的一个最重要的规范就是:服务的无状态性,即:
- 服务端不保存任何客户端请求者信息
- 客户端的每次请求必须具备
自描述信息
,通过这些信息识别客户端身份
带来的好处是什么呢?
- 客户端请求不依赖服务端的信息,任何多次请求不需要必须访问到同一台服务
- 服务端的集群和状态对客户端透明
- 服务端可以任意的迁移和伸缩
- 减小服务端存储压力
1.3.如何实现无状态
无状态登录的流程:
- 当客户端第一次请求服务时,服务端对用户进行信息认证(登录)
- 认证通过,将用户信息进行加密形成token,返回给客户端,作为登录凭证
- 以后每次请求,客户端都携带认证的token
- 服务端对token进行解密,判断是否有效。
整个登录过程中,最关键的点是什么?
token的安全性
token是识别客户端身份的唯一标示,如果加密不够严密,被人伪造那就完蛋了。
采用何种方式加密才是安全可靠的呢?
我们将采用JWT
来生成token,保证token的安全性
1.4.JWT
1.4.1.简介
JWT,全称是Json Web Token, 是JSON风格轻量级的授权和身份认证规范,可实现无状态、分布式的Web应用授权;官网:https://jwt.io
GitHub上jwt的java客户端:https://github.com/jwtk/jjwt
1.4.2.数据格式
JWT包含三部分数据:
-
Header:头部,通常头部有两部分信息:
- token类型,这里是JWT
- 签名算法,自定义
我们会对头部进行base64加密(可解密),得到第一部分数据
-
Payload:载荷,就是有效数据,一般包含下面信息:
- 标准载荷:JWT规定的信息,jwt的元数据:
- JTI: JWT的id,当前jwt的唯一标识(像身份证号)
- IAT: issue at 签发时间
- EXP:过期时间
- SUB:签发人
- …
- 自定义载荷:
- 用户身份信息,(注意,这里因为采用base64加密,可解密,因此不要存放敏感信息)
这部分也会采用base64加密,得到第二部分数据
- 标准载荷:JWT规定的信息,jwt的元数据:
-
Signature:签名,是整个数据的认证信息。一般根据前两步的数据,再加上服务的的密钥(secret)(不要泄漏,最好周期性更换),通过加密算法生成。用于验证整个数据完整和可靠性
生成的数据格式:
可以看到分为3段,每段就是上面的一部分数据。
什么是 JWT – JSON WEB TOKEN
傻傻分不清之 Cookie、Session、Token、JWT
JWT详细教程与使用
2.编写JWT工具
我们会用到比较流行的java语言的JWT工具,jjw
2.1.添加JWT依赖
我们需要先在项目中引入JWT依赖:
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.2</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.2</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.11.2</version><scope>runtime</scope></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId></dependency><!--json工具--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--日期时间工具类--><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId></dependency><!--redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
2.2.载荷对象
JWT中,会保存载荷数据,我们计划存储2部分:
- jti:jwt的id
- UserDetail:用户数据
为了方便后期获取,我们定义一个类来封装。
添加一个实体类,代表载荷信息
import lombok.Data;//载荷对象
@Data
public class Payload {/*** tocken的id*/private String jti;/*** 用户数据*/private UserDetail userDetail;
}
载荷中的UserDetail信息,也需要一个实体类表示,这里我们定义一个UserDetail类。
这里我们假设用户信息包含2部分:
- id:用户id
- username:用户名
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
public class UserDetail {/*** 用户id*/private Long id;/*** 用户名*/private String username;
}
2.3.工具
我创建一个JwtUtils 工具类,用来封装几个方法:
- createJwt() :生成JWT
- parseJwt() :验证并解析JWT
import com.example.jwt.constants.RedisConstants;
import com.example.jwt.dto.Payload;
import com.example.jwt.dto.UserDetail;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;import javax.crypto.SecretKey;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.UUID;
import java.util.concurrent.TimeUnit;public class JwtUtils {/*** JWT解析器*/private final JwtParser jwtParser;/*** 秘钥*/private final SecretKey secretKey;// @Autowiredprivate StringRedisTemplate redisTemplate;private final static ObjectMapper mapper = new ObjectMapper();public JwtUtils(String key) {// 生成秘钥secretKey = Keys.hmacShaKeyFor(key.getBytes(Charset.forName("UTF-8")));// JWT解析器this.jwtParser = Jwts.parserBuilder().setSigningKey(secretKey).build();}/*** 生成jwt,自己指定的JTI** @param userDetails 用户信息* @return JWT*/public String createJwt(UserDetail userDetails) {try {// 生成tokenidString jti=createJti();//存入redis中
// this.redisTemplate.opsForValue().set(RedisConstants.JTI_KEY_PREFIX+userDetails.getUsername(),jti,30, TimeUnit.MINUTES);return Jwts.builder().signWith(secretKey).setId(jti).claim("user", mapper.writeValueAsString(userDetails)).compact();} catch (JsonProcessingException e) {throw new RuntimeException(e);}}/*** 解析jwt,并将用户信息转为指定的Clazz类型** @param jwt token* @return 载荷,包含JTI和用户信息*/public Payload parseJwt(String jwt) {try {Jws<Claims> claimsJws = jwtParser.parseClaimsJws(jwt);Claims claims = claimsJws.getBody();Payload payload = new Payload();payload.setJti(claims.getId());payload.setUserDetail(mapper.readValue(claims.get("user", String.class), UserDetail.class));return payload;} catch (IOException e) {throw new RuntimeException(e);}}private String createJti() {return StringUtils.replace(UUID.randomUUID().toString(), "-", "");}/*** 刷新jwt有效期* @param username*/public void refreshJwt(String username) {String key= RedisConstants.JTI_KEY_PREFIX+username;//重置key的过期时间redisTemplate.expire(key,30,TimeUnit.MINUTES);}
}
2.4.测试
2.4.1.配置秘钥
在application.yml
文件中配置秘钥:
yy:jwt:key: helloWorldJavaAuthServiceSecretKe
定义一个配置类,注册JwtUtils
注入到Spring的容器。
import com.example.jwt.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class JwtConfig {@Value("${yy.jwt.key}")private String key;@Beanpublic JwtUtils jwtUtils(){return new JwtUtils(key);}
}
2.4.2.测试类
@Autowiredprivate JwtUtils jwtUtils;@Testpublic void test() {// 生成jwtString jwt = jwtUtils.createJwt(UserDetail.of(112L, "lele"));System.out.println("jwt = " + jwt);// 解析jwtPayload payload = jwtUtils.parseJwt(jwt);System.out.println("payload = " + payload);}
结果:
jwt = eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIyZTRkMGI1NjZiODY0YjUzODAwZTI3NGNhOWE0MTcxYSIsInVzZXIiOiJ7XCJpZFwiOjExMixcInVzZXJuYW1lXCI6XCJsZWxlXCJ9In0.NGa42tISwsLg_hyONasdGPGDigFFxkWbH04wd4ELztY
payload = Payload(jti=2e4d0b566b864b53800e274ca9a4171a, userDetail=UserDetail(id=112, username=lele))
相关文章:
安全认证--JWT介绍及使用
安全认证--JWT介绍及使用1.无状态登录原理1.1.什么是有状态?1.2.什么是无状态1.3.如何实现无状态1.4.JWT1.4.1.简介1.4.2.数据格式2.编写JWT工具2.1.添加JWT依赖2.2.载荷对象2.3.工具2.4.测试2.4.1.配置秘钥2.4.2.测试类1.无状态登录原理 有状态登录和无状态登录详…...
【计算机组成原理】计算机硬件的基础组成、认识各个硬件部件
计算机组成原理(一) 计算机内部是通过电信号传递数据 电信号:分为高电平和低电平,分别代表1/0 数字、文字、图像如何用二进制表示? CPU如何对二进制数进行加减乘除? 如何存储这些二进制数的? 如何从内存中取出想要的数…...
使用ChIPSeeker进行ChIP-seq, ATAC-seq,cuttag等富集峰的基因组注释
二代测序产生的数据类型 常规的下一代高通量测序(next generation sequencing, NGS)实验通常产生大量短片段(reads),通常我们需要将这些reads比对到参考基因组/转录组上,即将它们置于生物学上有意义的基因背景下,才能…...
第九届蓝桥杯省赛——7缩位求和
题目:在电子计算机普及以前,人们经常用一个粗略的方法来验算四则运算是否正确。比如:248 * 15 3720把乘数和被乘数分别逐位求和,如果是多位数再逐位求和,直到是1位数,得2 4 8 14 > 1 4 5;1 5 65…...
【c++】STL常用容器5—list容器
文章目录list基本概念list构造函数list赋值和交换list大小操作list插入和删除list数据存取list反转和排序list基本概念 功能:将数据进行链式存储。 链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链…...
【牛客刷题专栏】0x0D:JZ5 替换空格(C语言编程题)
前言 个人推荐在牛客网刷题(点击可以跳转),它登陆后会保存刷题记录进度,重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏:个人CSDN牛客刷题专栏。 题目来自:牛客/题库 / 在线编程 / 剑指offer: 目录前言问题…...
聚观早报 | 苹果2024年放弃高通;腾讯回应进军类 ChatGPT
今日要闻:苹果2024年放弃高通;腾讯回应进军类 ChatGPT;小米发布无线AR眼镜探索版;50%的美国企业已在使用ChatGPT;Snap推出ChatGPT驱动的聊天机器人 苹果2024年放弃高通 高通公司 CEO 兼总裁克里斯蒂亚诺・安蒙…...
Elasticsearch:如何正确处理 Elasticsearch 摄取管道故障
在我之前的文章 “Elastic:开发者上手指南” 中的 “Ingest pipeline” 章节中个,我有很多文章是关于 ingest pipeline 的。在今天的文章中,我将重点介绍如何处理在摄取管道中的错误。在我之前的文章 “Elasticsearch:如何处理 in…...
指标体系—北极星指标体系
北极星指标体系 每个产品都有很多指标,每个指标都反映了对应业务的经营情况。但是在实际业务经营中,却要求我们在不同的产品阶段寻找到合适的指标,让这个指标可以代表当前产品阶段的方向和目标,让这个指标不仅对业务经营团队,而且对产品的用户、对产品的价值都能有很好的…...
【操作系统】内存管理
虚拟内存 虚拟内存的目的是为了让物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。 为了更好的管理内存,操作系统将内存抽象成地址空间。每个程序拥有自己的地址空间,这个地址空间被分割成多个块,每一块称为一页。…...
家庭消耗品跟踪管理软件HomeLists
什么是 HomeLists ? HomeLists 是一款自托管耗材统计软件,能通过提醒等帮助您跟踪家庭消耗品。 安装 在群晖上以 Docker 方式安装。 在注册表中搜索 homelists ,选择第一个 aceberg/homelists,版本选择 latest。 本文写作时&…...
django模型简要(1)
1. AbstractUser(内置用户模型类)的使用 ### 需要在settings.py中添加如下: AUTH_USER_MODEL app.MyUser 说明:这是为了覆盖django默认的User model;app即模型所属app,MyUser即AbstractUser实现类。 2.on_delete选项 从django3.…...
【shell 编程大全】sed详解
sed详解1. 概述 今天单独拉出一章来讲述下sed命令。因为sed命令确实内容太多,不过也是比较灵活的,好了不废话了。我们开始吧 1.2 原理解析 shell脚本虽然功能很多,但是它最常用的功能还是处理文本文件,尤其是在正常的业务操作流程…...
关于sudo配置
前言这里做一个小补充,主要讲一下关于利用sudo对指令提权以及普通用户无法使用sudo指令的问题。在前面的文章【Linux】一文掌握Linux权限中,我们讲到了关于权限的一些问题。我们知道root身份下,一切畅通无阻,而权限只是用来限制我…...
EEGLAB处理运动想象脑电数据
最近在看论文时,经常看到作者处理数据的过程,之前都是一代而过,知道怎么处理就可以了,一直没有实践,最近需要一些特殊的数据,需要自己处理出来,这里尝试着自己用MATLAB处理数据,记录…...
span标签的使用场景
目录 前言 一、span标签是什么? 二、span常用 1.可以嵌套a标签。 2.直接使用 3.加样式使用 4.加按钮使用 5.加a标签的综合使用 6.跟table结合使用 总结 前言 本篇章主要记录一下开发日常中,所常遇见的使用span标签的场景。 一、span标签是什么…...
Kafka面试问题总结
kafka架构2.基础概念Producer(生产者) : 产生消息的一方。Consumer(消费者) : 消费消息的一方。Broker(代理) : 可以看作是一个独立的 Kafka 实例。多个 Kafka Broker 组成一个 Kafka Cluster。同时&#x…...
FPGA案例开发手册——基于全志T3+Logos FPGA核心板
前 言 本文档主要提供评估板FPGA端案例测试方法,适用的开发环境为Windows 7 64bit和Windows 10 64bit。 本文案例基于创龙科技的全志T3+Logos FPGA核心板,它是一款基于全志科技T3四核ARM Cortex-A7处理器 + 紫光同创Logos PGL25G/PGL50G FPGA设计的异构多核全国产工业核心板…...
或许你想要的画图工具在这里
之前文章发布后,有小伙伴问下面的画怎么画的(偷偷告诉你,其实我是用铅笔水彩笔画的),哈哈,开玩笑了。其实这些图都是用Excalidraw 画出来的。 我们平常不管是工作中,还是在日常写文章&#x…...
2023年功能测试还值得入行吗?
前言 鉴于笔者从13年入行IT行业,经历了只有开发没有测试的阶段,经历了14年只要会基本的功能测试在一线就能薪资过万的阶段,经历了17年只要会一点自动化,会一点性能就能蒙骗过面试官的阶段,更经历了19年所有面试官对于…...
2022-2023山东大学机器学习期末回忆及复习建议
2023年第一次闭卷考试,让我们准备时都很无力,不知道试题究竟是什么难度,是否要掌握手推公式还有一些晦涩的知识点之类的,看到试题才发现其实闭卷也有好处,与往年题相比难度下降了不少。 一、名词解释 1、测试集 2、Boo…...
基于ssm框架实现家庭理财收支系统(源码+数据库+文档)
一、项目简介 本项目是一套基于ssm框架实现家庭理财收支系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,…...
MyBatis - 09 - 自定义映射resultMap
文章目录1 准备工作1.1 建表1.2 创建实体类1.3 引出一个问题方案1方案2方案32.完整代码项目结构EmpMapper接口Emp类SqlSessionUtils工具类EmpMapper.xmljdbc.propertieslog4j.xmlmybatis-config.xmlResultMapTest完整代码在后面 1 准备工作 1.1 建表 t_emp 添加测试数据&…...
springBoot常见面试题(2023最新)
目录前言1.谈谈你对springBoot的理解2.为什么使用springBoot或springBoot的优点3. springBoot与springCloud 区别4.springBoot的核心配置文件有哪些,作用是什么5.springBoot配置文件有几种类型,区别是什么6.什么是热部署?springBoot怎么实现热…...
YOLOv5全面解析教程⑤:计算mAP用到的Numpy函数详解
作者 | Fengwen、BBuf 本文主要介绍在One-YOLOv5项目中计算mAP用到的一些numpy操作,这些numpy操作使用在utils/metrics.py中。本文是《YOLOv5全面解析教程④:目标检测模型精确度评估》的补充,希望能帮助到小伙伴们。 欢迎Star、试用One-YOLOv…...
Linux入门---基本指令(下)
这里写目录标题cattacmorelessheadtail一个思考题datecalfindwhichaliaswhereisgrepzip/unziptarbcuname快捷键tabCTRL c上下键CTRLrcat 这个指令的功能就是显示文件里面的内容: 我们首先使用下面的指令往一个文件里面循环输入内容: cnt0; while [ $c…...
mysql基础操作1
-- 创建数据库CREATE DATABASE st0203;-- 删除数据库DROP DATABASE st0203;-- 删除表DROP TABLE dept;-- 创建表CREATE TABLE dept(did int PRIMARY KEY auto_increment COMMENT主键(部门编号),deptName VARCHAR(20) NOT NULL COMMENT部门名称,address V…...
nginx-ingress部署+跨命名空间转发
nginx-ingress部署一、环境信息二、k8s环境搭建三、ingress环境搭建3.1 deploy.yaml文件3.2 service-nodeport.yaml文件四、按照业务建立service及ingress4.1 业务信息4.2 建立service4.3 创建ingress五、验证结果一、环境信息 k8s集群版本:1.23.6ingress版本&…...
耗时1个月整理的网络安全学习路线,不信还有比这更详细的
首先咱们聊聊,学习网络安全方向通常会有哪些问题 1、打基础时间太长 学基础花费很长时间,光语言都有几门,有些人会倒在学习linux系统及命令的路上,更多的人会倒在学习语言上; 2、知识点掌握程度不清楚 对于网络安全…...
ChatGPT进阶-提示词中文版
一、ChatGPT简介 ChatGPT 是 OpenAI 开发的人工智能聊天机器人。该聊天机器人基于 GPT-3.5 语言模型,经过训练可以对用户给出的指令做出详细响应。与其他聊天机器人不同,ChatGPT 可以回答后续问题、求解数学方程式、撰写文本、修复和调试代码以及总结文本…...
政府门户网站群集约化建设方案/小红书seo排名
记录一下Python的命名风格规范,文件名,包,模块,类,函数,变量….等等的命名风格,以及Google的Python命名规范。Python命名规范文件名全小写,可使用下划线包应该是简短的、小写的名字。如果下划线…...
连云港市网站平台/seo怎么收费的
方法1,登录阿里云控制台,登录服务器(需要服务器用户名和密码),因阿里云每天会自动备份数据,所以只需要把已备份好的文件下载到本地即可。 (吐槽:使用用户名和密码登录阿里云…...
广东网页空间网站平台/什么平台可以免费打广告
如果想跟我一起讨论的话,就快加入我的知识星球吧。星球里有一千多位同样爱好安全技术的小伙伴一起交流! 常用工具: Nmap使用详解Sqlmap使用详解Metasploit Framework(MSF)的使用MSF中kiwi模块的使用MSF中mimikatz模块的使用Msfvenonm生成后门木马...
内部网站建设党委/熊猫关键词工具
近期,一直在研究MySQL数据库,经常修改配置文件,导致MySQL数据库无法使用,不得不反复重装MySQL数据库。以下是在Windows7 64位操作系统下安装MySQL数据库的详细步骤,以供学习和参考:1、双击点击“mysql-inst…...
网站源码制作/百度联盟怎么加入赚钱
从十二星座分布图来看,我们不同星座位于不同的位置(废话),所以我们夏天旅游也要去不同的地方!要去就要去符合我们气场的地方,舒服。 这有关系吗???你又在骗我!…...
做cpa的博客网站类型/世界杯球队最新排名
先决条件:a. 启动Windows Management Instrumentation服务,开放TCP135端口。b. 本地安全策略的“网络访问: 本地帐户的共享和安全模式”应设为“经典-本地用户以自己的身份验证”。1. wmic /node:"192.168.1.20" /user:"domain\administr…...