JWT整合Springboot(1)

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

是的。所以,在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);

} catch (Exception e) {

map.put(“state”, false);

map.put(“msg”, e.getMessage());

}

return map;

}

}

数据库添加测试数据启动项目

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

通过postman模拟登录失败

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

通过postman模拟登录成功

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

编写测试接口

@PostMapping(“user/test”)

public Map<String, Object> test(String token) {

//通过拦截器验证了,token验证成功

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

map.put(“state”, true);

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

return map;

}

总结

对于面试还是要好好准备的,尤其是有些问题还是很容易挖坑的,例如你为什么离开现在的公司(你当然不应该抱怨现在的公司有哪些不好的地方,更多的应该表明自己想要寻找更好的发展机会,自己的一些现实因素,比如对于我而言是现在应聘的公司离自己的家更近,又或者是自己工作到达了迷茫期,想跳出迷茫期等等)

image

Java面试精选题、架构实战文档

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
or_FFFFFF,t_70,g_se,x_16)

编写测试接口

@PostMapping(“user/test”)

public Map<String, Object> test(String token) {

//通过拦截器验证了,token验证成功

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

map.put(“state”, true);

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

return map;

}

总结

对于面试还是要好好准备的,尤其是有些问题还是很容易挖坑的,例如你为什么离开现在的公司(你当然不应该抱怨现在的公司有哪些不好的地方,更多的应该表明自己想要寻找更好的发展机会,自己的一些现实因素,比如对于我而言是现在应聘的公司离自己的家更近,又或者是自己工作到达了迷茫期,想跳出迷茫期等等)

[外链图片转存中…(img-u6maZtp8-1714699981305)]

Java面试精选题、架构实战文档

整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 16
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值