iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >Java - JWT的简单介绍和使用
  • 820
分享到

Java - JWT的简单介绍和使用

java开发语言springboot 2023-10-27 17:10:10 820人浏览 安东尼
摘要

Java - Jwt的简单介绍和使用 前言一. JWT 基础知识1.1 session 案例测试1.2 JWT 结构1.2.1 Header1.2.2 Payload1.2.3 Signatu

Java - Jwt的简单介绍和使用

前言

目前自己在做一个云直播个人项目后端架构微服务,目前准备用JWT来做Token的校验。借此机会来复习和学习一遍JWT的相关知识。

一. JWT 基础知识

JWT的全称是JSON WEB Tokens主要是服务器认证相关信息之后,生成一种jsON数据,并通过一种算法(例如HMac)对其进行安全的签名加密。主要用于两个用途:

  • 数据交换:因为JWT使用JSON来存储相关数据,而JSON这一种数据格式可以在各方之间传递。
  • 安全验证:登录之后,后续的请求可以携带JWT,只有携带了JWT(认证Token)的请求才能够正常地访问到相关的数据及资源。

一般我们在开发过程中,凡是涉及到用户登录的,我们就需要去考虑用什么去存储用户登录的一个状态,本文只说两种:

  • session(基于cookie的实现):只不过session相关的数据存储于服务器。
  • JWT:一旦生成,一般就抛给客户端去保存。客户端只需要每次携带这个Token就可以正常地访问接口。

1.1 session 案例测试

我们来写一个简单的案例:pom依赖:

<parent>    <groupId>org.springframework.bootgroupId>    <artifactId>spring-boot-starter-parentartifactId>    <version>2.3.2.RELEASEversion>parent><dependencies>    <dependency>        <groupId>org.springframework.bootgroupId>        <artifactId>spring-boot-starter-webartifactId>    dependency>dependencies>

Controller代码:

@RestControllerpublic class UserController {    @GetMapping("/login")    public String login(httpservletRequest request) {        request.getSession().setAttribute("user", "Ljj");        return "Login Success";    }@GetMapping("/getUser")    public String getUser(HttpServletRequest request) {        String user = (String) request.getSession().getAttribute("user");        return user;    }}

那么我们项目启动之后,访问以下路径:http://localhost:8080/login,就能发现当前客户端会多出一个名为JSESSIONIDCookie
在这里插入图片描述
之后我们的每一次请求,都会自动携带上这个cookie去访问服务端:
在这里插入图片描述
如果我们采取session来存储用户信息,那么大致流程就是如下:

  1. 用户登录成功,那么我们就request.getSession().setAttribute("user"+userId, "用户信息")
  2. 此时服务端就会写入一个session来保存相关的数据(基于cookie实现)。因此客户端能看到一个名为JSESSIONIDCookie
  3. 后续的相关请求,都会自动携带这个Cookie,后端就可以取到这个用户信息了。

在这里插入图片描述

但是,采用session这种方式,是以本地缓存来存储相关的数据的,当有100个用户进行登录的时候,就需要在本地缓存存储100个信息。因此会给服务器带来一定的内存压力。

相关的数据存储于StandardSession.attributes字段中:

public class StandardSession implements HttpSession, Session, Serializable {protected ConcurrentMap<String, Object> attributes = new ConcurrentHashMap<>();}

因此现在主流的都是使用JWT来代替传统的session存储方案。

1.2 JWT 结构

JWT如上文所说,他是一个JSON串,但是它有着自己的特定结构:

Header.Payload.Signature

HeaderPayload部分都是一个base64编码串,三个结构之间通过 ” . “ 进行连接。

1.2.1 Header

Header头部,通常有两个部分组成:

  • alg:表示签名的算法类型,比如HMAC SHA256 或者 RSA
  • typ:代表这个token令牌的类型,比如JWT

案例如下:

{  "alg": "HS256",  "typ": "JWT"}

最后这个JSON串会通过Base64Url进行编码,然后作为JWT的第一部分。

1.2.2 Payload

JWT的第二部分就是这个Payload了,它的中文含义叫做:有效载荷。相当于我们HTTP请求的一个请求体了。一般用来存储我们实际要传递的数据。例如:

{  "sub": "1234567890",  "name": "John Doe",  "admin": true}

Payload本身还规定了几个属性,同时它可以分为三种类型:

标准注册声明:

  • iss (issuer):签发人。
  • exp (expiration time):过期时间。
  • sub (subject):主题。
  • aud (audience):接收方。
  • nbf (not before):生效时间。
  • iat (issued at):签发时间。
  • jti (jwt id):编号。

公共声明: 一般用于我们自己定义一些业务属性。


私有声明: 服务器和客户端共同定义的声明

这一部分的内容可见比较丰富,因为我们可以将自定义的属性塞进去,但是有一点我们需要格外地注意:Payload部分不建议添加敏感信息,例如密码、身份证等信息。因为Payload这一部分最终也是经过Base64Url进行编码,然后作为JWT的第二部分暴露给客户端。因此这个是可以被解码的。

1.2.3 Signature ☆

上面的两个JWT组成部分:HeaderPayload,我们知道它是由Base64Url进行编码的,那么自然而然的它就可以被解码。那么JWT安全性谈何而来?这就得看最后一个部分Signature签名了。他的作用一句话概括就是:对前两部分的内容进行算法签名,防止数据篡改。

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret)

这个代码是啥意思呢?

  1. 拿到经过Base64编码的HeaderPayload部分。以及我们自己提供的一个秘钥secret
  2. 使用Header中指定的签名算法:HMAC SHA256 进行签名。

签名的目的:

  1. 如果有人对头部以负载内容进行解码,然后篡改相关信息,在进行base64编码重新组合一个新的JWT
  2. 那么这个JWT传输给服务器后,服务器能够判断,新的头部和新的负载内容形成的签名和原有的不一致。
  3. 那么此时就能够判断这个JWT是不合法的。因为外部使用者无法得知你进行签名时的秘钥是什么。 因此通过修改JWT算出来签名是不一样的。

那么最后再来说下JWT的特点:

  • JWT的两个组成部分虽然是经过base64编码的,因此他可以被解码。但是JWT本身是可以被加密的。这样就更加安全。
  • JWT生成之后,不必存储在服务器端,就没有使用session存储那样,有着内存压力。
  • JWT 无法使服务器保存会话状态,当令牌生成后在有效期内无法取消也不能更改。
  • 安全:因为Token不是Cookie。我们只需要每次请求的时候携带Token即可。由于没有Cookie被发送,还有助于防止CSRF攻击。
  • 不要再JWT中存储一些敏感信息,一般都是存储userId

二. JWT 简单使用

首先准备pom依赖:

<dependency>    <groupId>junitgroupId>    <artifactId>junitartifactId>    <scope>testscope>dependency><dependency>    <groupId>com.auth0groupId>    <artifactId>java-jwtartifactId>    <version>3.19.1version>dependency>

2.1 生成JWT

public class JwtTest {    // 秘钥,你可以随便取,可以取的难一点    public static final String SECRET = "ASD!@#F^%A";    @Test    public void testTokenCreate() {        HashMap<String, Object> headers = new HashMap<>();        // 过期时间,60s        Calendar expires = Calendar.getInstance();        expires.add(Calendar.SECOND, 600);        String jwtToken = JWT.create()                // 第一部分Header                .withHeader(headers)                // 第二部分Payload                .withClaim("userId", 20)                .withClaim("userName", "LJJ")                .withExpiresAt(expires.getTime())                // 第三部分Signature                .sign(AlGorithm.HMAC256(SECRET));        System.out.println(jwtToken);    }}

结果如下:看红圈的两个"."符号,可见JWT的格式和第一章节描述的相吻合。
在这里插入图片描述

那么拿到令牌了,我们接下来就是根据令牌去解析数据。

2.2 解析JWT

注意:这里你要把2.1节生成的token自己复制一下,贴到代码里面。

@Testpublic void testReadJWT() {    // 创建一个验证的对象    JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();    DecodedJWT verify = jwtVerifier.verify("eyJ0eXAiOiJKV1QiLCJhbGCiOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6IkxKSiIsImV4cCI6MTY2NzcyMTMzMiwidXNlcklkIjoyMH0.AJA88B0F-zKEJUCIGp9kSx2TlbpoyH88GzEn-9xN5XI");    System.out.println(verify.getClaim("userId").asInt());    System.out.println(verify.getClaim("userName").asString());    System.out.println("过期时间:" + verify.getExpiresAt());}

结果如下:
在这里插入图片描述

2.3 常见的异常

这里贴出4个常见的异常,如果JWT校验不通过,就会抛出异常:

  • SignatureVerificationException:签名不一致。
  • TokenExpiredException:令牌过期。
  • AlgorithmMismatchException:算法不匹配异常。
  • InvalidClaimException:失效的Payload异常。一般存在于这种情况:获取token的服务器比使用token的服务器时钟快,请求分发到时间慢的服务器上导致token还没生效。

来源地址:https://blog.csdn.net/Zong_0915/article/details/127714702

--结束END--

本文标题: Java - JWT的简单介绍和使用

本文链接: https://www.lsjlt.com/news/499119.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java - JWT的简单介绍和使用
    Java - JWT的简单介绍和使用 前言一. JWT 基础知识1.1 session 案例测试1.2 JWT 结构1.2.1 Header1.2.2 Payload1.2.3 Signatu...
    99+
    2023-10-27
    java 开发语言 spring boot
  • jwt介绍和PHP的使用
    适用于分布式单点登录(SSO) 流程 客户端输入账号密码登录; 服务端判断登录信息,用户登录成功返回客户端token; 客户端存储token,每个请求都需要传递token到服务端; 服务端验证token的有效期,返回对应的信息; 构成 分为...
    99+
    2023-10-20
    1024程序员节 php
  • Java中&和&&的区别简单介绍
    & 按位运算符,逻辑运算符 && 逻辑运算符 相同点:只要有一端为假,则语句不成立 假设有三个参数 int x = 1; int y = 2; int q =...
    99+
    2022-11-12
  • Android Retrofit的简单介绍和使用
    Retrofit与okhttp共同出自于Square公司,retrofit就是对okhttp做了一层封装。把网络请求都交给给了Okhttp,我们只需要通过简单的配置就能使用re...
    99+
    2022-06-06
    retrofit Android
  • C# FileStream简单介绍和使用
    FileStream 是 C# 中用于操作文件的类,它提供了一种以字节为单位读取和写入文件的功能。使用 FileStream,可以实...
    99+
    2023-08-08
    C#
  • Python JWT 介绍和使用详解
    1. JWT 介绍 ​jwt( JSON Web Tokens ),是一种开发的行业标准 RFC 7519 ,用于安全的表示双方之间的声明。目前,jwt广泛应用在系统的用户认证方面,特别是现在前后端分离项...
    99+
    2022-06-02
    Python JWT使用 Python JWT
  • Java Jwt库的简介及使用详解
    JWT介绍 JWT概念 JWT , 全写JSON Web Token, 是开放的行业标准RFC7591,用来实现端到端安全验证. 简单来说, 就是通过一些算法对加密字符串和JSON对...
    99+
    2022-11-12
  • Java Jwt库的简介及使用方法
    这期内容当中小编将会给大家带来有关Java Jwt库的简介及使用方法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。JWT介绍JWT概念JWT , 全写JSON Web Token, 是开放的行业标准RFC...
    99+
    2023-06-25
  • python使用sqlite简单介绍
    python连接sqlite非常简单,基本步骤如下: 用sqlite3.connect创建数据库连接,假设连接对象为conn 如果该数据库操作不需要返回结果,就直接用conn.execute查询,如建表、删表、添加、修改删除数据...
    99+
    2023-01-31
    简单 python sqlite
  • 单点登录的三种方式和JWT的介绍与使用
    单点登录三种方式 单点登录的三种实现方式: 分别为session广播机制;cookie+redis;token session广播机制指在一个集群中的一个模块登录后,然后把该sess...
    99+
    2023-03-24
    单点登录 JWT介绍 JWT使用
  • Java中Range函数的简单介绍
    目录前言Range语法IntStream范围的语法LongStream范围的语法Range函数在Java中是如何工作的?Java中的Range示例前言 在Java中,Range方法在...
    99+
    2022-11-13
  • Micronaut框架的简单使用介绍
    目录什么是Micronaut主要特点入门依赖注入构建HTTP服务器阻塞HTTP反应式IO构建HTTP客户端声明性HTTP客户端编程HTTP客户端Micronaut客户端联合项目特征现...
    99+
    2022-11-12
  • 简单介绍如何使用GitHub
    在现代互联网社会中,程序员们都离不开GitHub这个开源代码仓库。它不仅可以用于托管代码,还可以与其他合作者共同合作开发同一项目。但是,对于初次使用GitHub的人来说,可能会感到有些困惑。在本文中,我们将介绍如何使用GitHub。首先,需...
    99+
    2023-10-22
  • MinIO的介绍以及简单的使用
    什么是MinIO MinIO是在GUN Affero通用公共许可证 v3.0 下发布的高性能对象存储.他与AmazonS3云存储服务API兼容.使用MinIO为机器学习,分析和应用程序数据工作负载构建高性能基础架构. MinIO是一个高...
    99+
    2023-10-26
    java Powered by 金山文档
  • Python运算符的使用简单介绍
    目录1、算术运算符2、赋值运算符3、比较运算符4、逻辑运算符5、位运算符6、运算符优先级和结合性1、算术运算符 Python 中常用运算符: 运算符说明实例结果+加22.4 + 15...
    99+
    2022-11-11
  • Java中的乐观锁和悲观锁简单介绍
    这篇文章主要介绍“Java中的乐观锁和悲观锁简单介绍”,在日常操作中,相信很多人在Java中的乐观锁和悲观锁简单介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中的乐观锁和悲观锁简单介绍”的疑惑有所...
    99+
    2023-06-02
  • 使用Nginx和Lua进行JWT校验介绍
    目录前言Lua脚本nignx.conf配置Dockerfile配置前言 因为不涉及到数据库和其它资源的依赖,jwt本身也是无状态的。因此鉴权服务没有再基于Java或者其它语言来做。而...
    99+
    2022-11-12
  • 简单介绍Git和GitHub的区别
    在软件开发和版本控制的领域,Git和GitHub是两个经常被提及的工具。尽管二者常常被混淆,甚至被认为是同一个概念,他们有着不同的功能和作用。本文将简单介绍Git与GitHub的区别。Git是一款免费开源的分布式版本控制系统。它最初由Lin...
    99+
    2023-10-22
  • Android popupwindow简单使用方法介绍
    先看下效果 1.首页 package com.yskj.jh.demopopupwindow; import android.content.Context; impo...
    99+
    2022-06-06
    方法 popupwindow Android
  • Android学习之介绍Binder的简单使用
    前言 最近因为公司项目需求,需要远程调度启动客户端输入法输入内容。 这就是大致的需求流程,这篇首先讲远程与服务控制端通讯。首先控制服务端定义好一个Service,且在Ser...
    99+
    2022-06-06
    android学习 binder Android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作