JWT整合Springboot

“alg”: “HS256”,

“typ”: “JWT”

}

Payload

  • 令牌的第二部分是有效负载,其中包含声明。声明是有关实体

  • (通常是用户)和其他数据的声明。同样的,它会使用 Base64 编码组成 JWT 结构的第二部分

{

“sub”: “1234567890”,

“name”: “John Doe”,

“admin”: true

}

Signature

  • 前面两部分都是使用 Base64 进行编码的,即前端可以解开知道里面的信息。Signature 需要使用编码后的 header 和 payload以及我们提供的一个密钥,然后使用 header 中指定的签名算法(HS256)进行签名。签名的作用是保证 JWT 没有被篡改过

  • 如:HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload),secret);

签名目的

最后一步签名的过程,实际上是对头部以及负载内容进行签名,防止内容被窜改。如果有人对头部以及负载的内容解码之后进行修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的。如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的。

信息安全问题

在这里大家一定会问一个问题:Base64是一种编码,是可逆的,那么我的信息不就被暴露了吗?

是的。所以,在JWT中,不应该在负载里面加入任何敏感的数据。在上面的例子中,我们传输的是用户的User ID。这个值实际上不是什么敏感内容,一般情况下被知道也是安全的。但是像密码这样的内容就不能被放在JWT中了。如果将用户的密码放在了JWT中,那么怀有恶意的第三方通过Base64解码就能很快地知道你的密码了。因此JWT适合用于向Web应用传递一些非敏感信息。JWT还经常用于设计用户认证和授权系统,甚至

实现Web应用的单点登录。

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VooaYcxY-1637927753210)(JWT.assets/20201022130536633.png)]

2.使用JWT


引入依赖

com.auth0

java-jwt

3.4.0

生成token

@Test

void contextLoads() {

HashMap<String, Object> map = new HashMap<>();

Calendar instance=Calendar.getInstance();

instance.add(Calendar.SECOND,200);

//获取token

String token = JWT.create().withHeader(map) //header,默认,可以不写

.withClaim(“userId”, 23)

.withClaim(“username”, “xpp”) //palyload

.withExpiresAt(instance.getTime()) //指定令牌的过期时间

.sign(Algorithm.HMAC256(“xpp@ll”));//签名,指定秘钥

System.out.println(token);

}

生成结果

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Mzc5MDM2OTksInVzZXJJZCI6MjMsInVzZXJuYW1lIjoieHBwIn0.dnWldEBILZpt7Upz762VcMm-uTU9HI5jK-AHk3XyX0s

根据令牌和签名解析数据

@Test

public void test(){

//创建验证对象

JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(“xpp@ll”)).build();

//验证token

DecodedJWT verify = jwtVerifier.verify(“eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Mzc5MDM2OTksInVzZXJJZCI6MjMsInVzZXJuYW1lIjoieHBwIn0.dnWldEBILZpt7Upz762VcMm-uTU9HI5jK-AHk3XyX0s”);

//获取存入palyload的信息

Date expiresAt = verify.getExpiresAt();

System.out.println(expiresAt);

System.out.println(verify.getClaim(“userId”).asInt());

}

常见异常信息

  • SignatureVerificationException: 签名不一致异常

  • TokenExpiredException: 令牌过期异常

  • AlgorithmMismatchException: 算法不匹配异常

  • InvalidClaimException: 失效的payload异常

3.整合Springboot


引入依赖

com.auth0

java-jwt

3.4.0

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.1.3

org.projectlombok

lombok

1.18.12

com.alibaba

druid

1.1.19

mysql

mysql-connector-java

5.1.38

配置

server.port=8989

spring.application.name=jwt

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/jwt?characterEncoding=UTF-8

spring.datasource.username=root

spring.datasource.password=root

mybatis.type-aliases-package=com.baizhi.entity

mybatis.mapper-locations=classpath:com/baizhi/mapper/*.xml

logging.level.com.baizhi.dao=debug

数据库表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pbT5Xx0M-1637927753266)(JWT.assets/image-20211126185747996.png)]

DROP TABLE IF EXISTS user;

CREATE TABLE user (

id int(11) NOT NULL AUTO_INCREMENT COMMENT ‘主键’,

name varchar(80) DEFAULT NULL COMMENT ‘用户名’,

password varchar(40) DEFAULT NULL COMMENT ‘用户密码’,

PRIMARY KEY (id)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

实体类

@Data

@Accessors(chain=true)

public class User {

private String id;

private String name;

private String password;

}

开发DAO接口和mapper.xml

@Mapper

public interface UserDAO {

User login(User user);

}

select * from user where name=#{name} and password = #{password}

开发Service 接口以及实现类

public interface UserService {

User login(User user);//登录接口

}

@Service

@Transactional

public class UserServiceImpl implements UserService {

@Autowired

private UserDAO userDAO;

@Override

@Transactional(propagation = Propagation.SUPPORTS)

public User login(User user) {

User userDB = userDAO.login(user);

if(userDB!=null){

return userDB;

}

throw new RuntimeException(“登录失败~~”);

}

}

编写JWT工具类

/**

  • @Auther: xppll

  • @Date: 2021/11/26 13:25

*/

public class JWTUtils {

//秘钥

private static final String TOKEN = “xpp@ll”;

/**

  • 生成token(head.playload.sing)

  • @param map 用户传过了的信息,例如id等

  • @return

*/

public static String getToken(Map<String, String> map) {

Calendar instance = Calendar.getInstance();

//设置默认7天过期

instance.add(Calendar.DATE, 7);

//创建jwt builder

JWTCreator.Builder builder = JWT.create();

//payload

map.forEach((k, v) -> {

builder.withClaim(k, v);

});

//指定令牌过期时间

String token = builder.withExpiresAt(instance.getTime())

//sign,传入加密盐

.sign(Algorithm.HMAC256(TOKEN));

return token;

}

/**

  • 验证token合法性

  • @param token

*/

public static void verify(String token) {

JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);

}

/**

  • 获取token信息方法

  • @param token

  • @return

*/

public static DecodedJWT getTokenInfo(String token) {

DecodedJWT verify = JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);

return verify;

}

}

开发controller

/**

  • @Auther: xppll

  • @Date: 2021/11/26 14:07

*/

@RestController

@Slf4j

public class UserController {

@Autowired

private UserService userService;

@GetMapping(“/user/login”)

public Map<String, Object> login(User user) {

Map<String, Object> map = new HashMap<>();

try {

User userDB = userService.login(user);

//用来存放payload

Map<String, String> payload = new HashMap<>();

payload.put(“id”, userDB.getId());

payload.put(“name”, userDB.getName());

//生成JWT的令牌

String token = JWTUtils.getToken(payload);

map.put(“state”, true);

map.put(“msg”, “成功”);

//成功返回token信息

map.put(“token”, token);

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

每年转战互联网行业的人很多,说白了也是冲着高薪去的,不管你是即将步入这个行业还是想转行,学习是必不可少的。作为一个Java开发,学习成了日常生活的一部分,不学习你就会被这个行业淘汰,这也是这个行业残酷的现实。

如果你对Java感兴趣,想要转行改变自己,那就要趁着机遇行动起来。或许,这份限量版的Java零基础宝典能够对你有所帮助。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
mg-8FjyPRXR-1713211230232)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

每年转战互联网行业的人很多,说白了也是冲着高薪去的,不管你是即将步入这个行业还是想转行,学习是必不可少的。作为一个Java开发,学习成了日常生活的一部分,不学习你就会被这个行业淘汰,这也是这个行业残酷的现实。

如果你对Java感兴趣,想要转行改变自己,那就要趁着机遇行动起来。或许,这份限量版的Java零基础宝典能够对你有所帮助。

[外链图片转存中…(img-fEtVmjk4-1713211230232)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 28
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值