JWT代码实现

这篇具有很好参考价值的文章主要介绍了JWT代码实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是 JWT?

JSON Web Token,通过数字签名的方式,以 JSON 对象为载体,在不同的服务终端之间安全的传输信 息。(将信息进行封装,以 JSON 的形式传递) JWT 有什么用? JWT 最常见的场景就是授权认证,一旦用户登录,后续每个请求都将包含 JWT,系统在每次处理用户请 求的之前,都要先进行 JWT 安全校验,通过之后再进行处理。

前后端传输数据时,一般是使用 session 或是 cookie,但是都相对有自己的弊端,JWT 是利用 token 来对用户身份进行验证的方式,具体流程是前端使用用户名和密码来登录,服务器收到请求后验 证用户名和密码,验证成功后,服务器会签发一个 token ,将 token 返回给前端,前端将收到的 token 存储起来,在每次请求资源时都必须携带 token,服务器收到请求,会先验证 token 是否有效,验证成 功就给前端返回请求的数据。

优势

这种基于 token 的认证方式相对于传统的 session 认证方式更节约服务器资源,token 在服务端不需要 存储 session 信息,因为 token 自身包含了所有登录用户的信息,所有可以减轻服务端压力。

JWT 的组成 JWT 由 3 部分组成,用.拼接

eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRvbSIsInJvbGUiOiJhZG1pbiI
sInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2NjU1NTAzNDIsImp0aSI6IjBiOWU3MmRmLTQ0NjQtNDV
kYy04ODMwLWU3NTJkMjg1OGQ0MCJ9.00-RQiPM_a9_0q03CrmcrOBMaLbcfWw85Mbc7xc4AtU

 这三部分分别是:

Header

包含token 类型和加密算法的名称

{
//类型
'typ': 'jwt',
//算法
'alg': 'HS256'
}

将信息进行base64编码(转码)

Payload //载荷(存储有效信息)

包含标准中注册的声明、公共的声明、私有的声明,其实就是信息安全的分类,存储主要的信息 同时也需要将信息进行base64编码(转码) 

{
"sub": '1234567890',
"name": 'john',
"amdin":true
}

Signature //签名

将转码后的 header 和 payload 用.进行拼接之后再用使用 HS256 进行加盐加密,就构成了 jwt 的第三 部分

其实就是由转码后的 header 和 payload 进行再次加密后的数据

//对转码后的 Header 和 Payload 用.进行拼接
var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
//使用 HS256 进行加盐加密
var signature = HMACSHA256(encodedString, 'secret');

项目搭建

pom.xml

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- jdk1.8 以上要加-->
<!-- <dependency>-->
<!-- <groupId>javax.xml.bind</groupId>-->
<!-- <artifactId>jaxb-api</artifactId>-->
<!-- <version>2.3.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.sun.xml.bind</groupId>-->
<!-- <artifactId>jaxb-impl</artifactId>-->
<!-- <version>2.3.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.sun.xml.bind</groupId>-->
<!-- <artifactId>jaxb-core</artifactId>-->
<!-- <version>4.0.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>javax.activation</groupId>-->
<!-- <artifactId>activation</artifactId>-->
<!-- <version>1.1</version>-->
<!-- </dependency>-->

测试加密/解密

如何使用 jwt

加密

在这里我们测试一下 jwt 的加密和解密过程来了解 jwt

首先使用 JwtBuilder 来创建 jwt 对象 ,根据三部分先加入 jwt 的 header,使用.setHeaderParam() 这里使用链式编程增加参数,再加入载荷 payload 使用 .claim() 方法 还可以加入主题和有效时间(一 天的有效时间 System.currentTimeMillis() + time),id 用了 UUID

定义全局签名信息用于解密,使用 .sigWith(算法,签名key) 加密,调用 .compact() 进行拼接

输出 JWT 数据

import io.jsonwebtoken.*;
import javafx.scene.chart.PieChart;
import sun.awt.SunHints;
import java.security.Key;
import java.security.KeyException;
import java.util.Date;
import java.util.UUID;
public class Test {
private long time = 1000*60*60*24;
private String signature = "amdin";//签名信息(解密)
@org.junit.Test
public void jwt(){
JwtBuilder jwtBuilder = Jwts.builder();//用来构建jwt对象
String jwtToken = jwtBuilder
//Header
.setHeaderParam("typ","jwt")
.setHeaderParam("alg","HS256")
//Payload
.claim("username","tom")
.claim("role","admin")
.setSubject("admin-test")//主题
.setExpiration(new Date(System.currentTimeMillis() + time))//有效
时间 当前时间+一天 24h
.setId(UUID.randomUUID().toString())
//Signature
.signWith(SignatureAlgorithm.HS256,signature)
.compact();//拼接三部分
System.out.println(jwtToken);
}
@org.junit.Test
public void parse(){
String token =
"eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRvbSIsInJvbGUiOiJhZG1pbi
IsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2NjU1NTAzNDIsImp0aSI6IjBiOWU3MmRmLTQ0NjQtND
VkYy04ODMwLWU3NTJkMjg1OGQ0MCJ9.00-RQiPM_a9_0q03CrmcrOBMaLbcfWw85Mbc7xc4AtU";
JwtParser jwtParser = Jwts.parser();
//解密 通过签名进行解析
Jws<Claims> claimsJws =
jwtParser.setSigningKey(signature).parseClaimsJws(token);
//把解析的数据存入对象中
Claims claims = claimsJws.getBody();
//从对象中取出数据
System.out.println(claims.get("username"));
System.out.println(claims.get("role"));
System.out.println(claims.getId()); //ID
System.out.println(claims.getSubject()); //签名
System.out.println(claims.getExpiration()); //有效期截至时间
}
}

对 token 进行解密

首先 使用 Jwts.parser() 对象的 .setSigningkey(签名key)解密 .parseClaimsJws(token)会把所有信息解 析成 Claims,Claims 相当于我们的各种数据,通过签名对 token 进行解析拿到 Claims ,调用 .getBody 方法把封装的数据放到 claims 对象当中,之后就可以使用 对象 .get 方法取出数据,从而将 jwttoken 中解析出我们的数据。

Spring boot + vue + Jwt

简单的小项目来了解 jwt 具体用法

作为java web中的一个令牌,就像之前测试加密时,用户在登录后,访问咱们的登录接口,登录接口判 断登录成功后把用户信息转为 jwtoken(jwt工具类,跟上面加密过程一样) 存入用户信息中,把整个 用户对象给到前端。

controller

@GetMapping("/login")
public User login(User user){
if (USERNAME.equals(user.getUsername()) &&
PASSWORD.equals(user.getPassword())){
//添加token
user.setToken(JwtUtil.createToken());
return user;
}
return null;
}

 JwtUtil

private static long time = 1000*60*60*24;
private static String signature = "amdin";
public static String createToken(){
JwtBuilder jwtBuilder = Jwts.builder();//用来构建jwt对象
String jwtToken = jwtBuilder
//Header
.setHeaderParam("typ","jwt")
.setHeaderParam("alg","HS256")
//Payload
.claim("username","admin")
.claim("role","admin")
.setSubject("admin-test")//签名
.setExpiration(new Date(System.currentTimeMillis() + time))//有效
时间 当前时间+一天 24h
.setId(UUID.randomUUID().toString())
//Signature
.signWith(SignatureAlgorithm.HS256,signature)
.compact();//拼接三部分
return jwtToken;
}

 前端拿到数据,从请求中拿到 JSON 进入 home 页面

this.$refs.loginForm.validate((valid) => {
if (valid) {
//点击登录后的一个入口
// alert('submit!');
//把全局this记录下来
let _this = this
//axios的get请求需要套{params:_this},需要把loginForm对象给到
后台
this.$axios.get('http://localhost:8080/login',
{params:_this.loginForm}).then(function (response) {
console.log(response.data)
//使用 localStorage 进行存储 access-admin(localStorage
只能存储字符串)
localStorage.setItem('accessadmin',JSON.stringify(response.data))//JSON.stringify JSON转字符串的方法
//去到登录成功的页面
_this.$router.replace({path:'/home'})
})
} else {
this.$message.error('请输入所有字段!');
return false;
}
});

 登录后在请求中拿到用户数据(保证安全性不显示)

JWT代码实现

 home页面,将 JSON 取出并还原存入全局变量 admin 中,就可以从 admin 中取出数据显示到页面上

JWT代码实现

 JWT代码实现

 

created() {
this.admin = JSON.parse(window.localStorage.getItem('access-admin'))
}

登录成功后切换页面进行验证(因为每次跳转都需要向后台发请求,重复代码太多,把验证抽象出来, 实现代码复用,所以写到路由当中,每个页面的跳转都需要经过路由)俗称路由守卫,首先验证用户是 否登录,(取出 JSON 还原 判断)如果没有登录直接跳转到登录页面,接着检验token合法性,访问后 台/checkToken,把保存的 token 传到后台进行认证,后台返回布尔值,如果是 flase 提示校验失败跳 转到错误页面,正确直接往后运行

router.beforeEach((to,from,next)=>{
if (to.path.startsWith('/login')) {
window.localStorage.removeItem('access-admin')
next()
} else {
//验证是否登录
let admin = JSON.parse(window.localStorage.getItem('access-admin'))
if (!admin){
next({path:'/login'})
} else {
//校验token合法性
axios({
url:'http://localhost:8081/checkToken',
method:'get',
headers:{
token:admin.token//类似?传参
}
}).then((response)=>{
console.log(response.data)
//给一个布尔值,如果是flase,提示校验失败,给到错误页面
if (!response.data){
console.log('校验失败')
next({path:'/error'})
}
})
next()
}
}
})

后台验证

从 headers 中获取前端给的 token,进入工具类中进行验证

controller

@GetMapping("/checkToken")
public Boolean checkToken(HttpServletRequest request){
//因为前端是存入 headers 中
String token = request.getHeader("token");
return JwtUtil.checkToken(token);
}

判断 token 是否为空,使用 Jwts.parser()方法,类似之前的解密 token ,解析签名 signature ,解析后 拿到集合 获取 JwtToken ,不需要拿出数据,只需要判断解析是否异常,如果解析异常说明 token 失 效,如果有异常返回 false,反之则返回 true,给到前端

JwtUtil

public static boolean checkToken(String token){
if (token == null){
return false;
}
try {
//判断token是否有效,如果解析异常说明token无效
Jws<Claims> claimsJws =
Jwts.parser().setSigningKey(signature).parseClaimsJws(token);
} catch (Exception e) {
return false;
}
return true;
}

 在前端 console.log(response.data) 中可以看出是否有效

 JWT代码实现

 验证,改变 token 有效时间文章来源地址https://www.toymoban.com/news/detail-481143.html

private static long time = 1000*5;

到了这里,关于JWT代码实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • HTTPS加密原理,搞懂什么是对称加密、非对称加密、证书、数字签名

    众所周知,http协议是一种未加密的协议,我们未加密的数据,在传输的过程中会经过一个又一个的物理节点,如果被人通过抓包的方式拿到了我们的数据,将会给我们造成无法估量的损失。 为了解决解决这个问题,https应运而生。https通过加密的手段,保障的数据的安全性。

    2024年02月01日
    浏览(37)
  • python实现对称加密、数字签名、数字证书颁发

    一.开发目的: 理解开源密码库实现的基本架构,熟悉对称算法的加解密函数封装与调用,并能能够利用开源设计接口进行二次封装,并实现一个界面友好,功能正确的采用对称算法的文件加解密工具。 二.开发环境: 硬件环境: 处理器:Intel®Core™i5-1035G1 CPU @1.00GHz 1.19GHz2

    2024年02月13日
    浏览(27)
  • Java实现基于RSA的数字签名

    1、加密保证了数据接受方的数据安全性。加密的作用是防止泄密。 2、签名保证了数据发送方的数据安全性。签名的作用是防止篡改。 问题:在比特币中,怎么证明这个交易是你发布的? 这是就需要用到数字签名,数字签名大概可已描述为:用私钥加密,用公钥解密。发布

    2024年02月11日
    浏览(38)
  • PHP 对PDF文件实现数字签名

    PHP通过TCPDF库对生成的PDF文件进行数字签名。 效果如下: 这个是因为签名证书不在可信任证书列表中。 目录 准备数字证书 1.申请数字证书 2.自签名证书 安装TCPDF 证书签名 设置证书路径 设置证书信息 设置文档签名 设置签名外观 图像签名外观 空签名外观 完整代码 总结 可以

    2024年02月11日
    浏览(27)
  • SpringCloudGateway实现数字签名与URL动态加密

    再网络传递数据的时候,为了防止数据被篡改,我们会选择对数据进行加密,数据加密分为对称加密和非对称加密。其中RSA和AES,TLS等加密算法是比较常用的。 对称加密是指加密和解密使用相同的密钥的加密方法。其基本流程包括以下步骤: 密钥生成 : 双方协商生成一个共

    2024年02月07日
    浏览(26)
  • 【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全

    系列索引:【图解安全加密算法】加密算法系列索引 Python保姆级实现教程 | 物联网安全 | 信息安全 DSA数字签名算法基于SHA1哈希算法,关于SHA1的实现看另一篇文章。 数字签名标准(DSS)由NIST公布,该标准能够使接收者能够验证数据的完整性和数据发送者的身份而制定,所采用

    2024年02月06日
    浏览(35)
  • 国密算法 SM2 公钥加密 数字签名 密钥交换 全网最高效的开源python代码

    此前发布过SM2、SM3、SM4、ZUC等文章,以及开源的完整python代码。近些天看到一篇电子科大兰同学的硕士毕业论文(兰修文. ECC计算算法的优化及其在SM2实现中的运用[D]. 成都: 电子科技大学, 2019),文中采用预计算加速SM2椭圆曲线基点点乘,将这个思路用python代码实现后,实测

    2024年02月09日
    浏览(33)
  • 安装软件和驱动程序需要微软数字签名无法安装?数字签名和数字证书区别

    1.安装软件和驱动程序需要微软数字签名无法安装 windows安装exe安装包时: 1.1  解决方法: 1.2           这个问题需要安装驱动补丁进行更新驱动操作,如:Windows6.1-sha2补丁.msu 1.3           这种属于签名问题,解决方法: 1..进入“控制面板”,查看方式为大图标,点击“

    2024年02月05日
    浏览(47)
  • Java - 数字签名与数字证书

    SSL是一种安全协议,用于在网络传输中提供数据加密、身份验证和完整性保护。它基于传输层协议(如TCP),并为其提供加密和安全功能。 对称加密和非对称加密 : 对称加密 :使用相同的密钥进行加密和解密。 非对称加密 :使用两个密钥:公钥用于加密,私钥用于解密。

    2024年01月24日
    浏览(29)
  • RSA数字签名认证

    1.数字签名 数字签名是一种用于验证数据完整性和身份认证的加密技术。使用数字签名可以提高数据传输的安全性和可靠性,确保数据在传输过程中不被篡改或伪造,并且可以确定数据的发送者身份。 数字签名可以确保数据的完整性和安全性。 2.步骤 发送方使用 私钥 对要发

    2024年02月04日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包