springboot+jwt令牌简单登录案例

news/2024/9/23 6:32:25/

1. 什么是JWT?JSON Web Token

JSON Web Token (JWT)是⼀个开放标准(RFC 7519),它定义了⼀种紧凑的、⾃包含的⽅式,⽤于 作为JSON对象在各⽅之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

1.1 什么时候应该⽤JWT?

Authorization (授权) : 这是使⽤JWT的最常⻅场景。⼀旦⽤⼾登录,后续每个请求都将包含 JWT,允许⽤⼾访问该令牌允许的路由、服务和资源。单点登录是现在⼴泛使⽤的JWT的⼀个特 性,因为它的开销很⼩,并且可以轻松地跨域使⽤。

• Information Exchange (信息交换) : 对于安全的在各⽅之间传输信息⽽⾔,JSON Web Tokens⽆ 疑是⼀种很好的⽅式。因为JWT可以被签名,例如,⽤公钥/私钥对,你可以确定发送⼈就是它们 所说的那个⼈。另外,由于签名是使⽤头和有效负载计算的,您还可以验证内容没有被篡改。

1.2 认证流程

 1.3 JWT优势在哪?

1. 简洁(Compact): 可以通过URL,POST参数或者在HTTP header发送,数据量⼩,传输速度快 2. ⾃包含(Self-contained):负载中包含了所有⽤⼾所需要的信息,避免了多次查询数据库 因为Token是 以JSON加密的形式保存在客⼾端的,所以JWT是跨语⾔的,原则上任何web形式都 ⽀持。 3.因为Token是 以JSON加密的形式保存在客⼾端的,所以JWT是跨语⾔的,原则上任何web形式都 ⽀持。

4. 不需要在服务端保存会话信息,特别适⽤于分布式微服务。

2.具体实现

2.1 创建实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class User {private Integer id;private String name;private String password;
}

2.2 创建jwt工具类


public class JWTUtil {/*** 密钥要*/private static String SECRET = "axingixngixng%!save";/*** 传入payload信息获取token* @param map payload* @return token*/public static String getToken(Map<String, String> map) {JWTCreator.Builder builder = JWT.create();//payloadmap.forEach(builder::withClaim);Calendar instance = Calendar.getInstance();instance.add(Calendar.DATE, 3); //默认3天过期builder.withExpiresAt(instance.getTime());//指定令牌的过期时间return builder.sign(Algorithm.HMAC256(SECRET));}/*** 验证token*/public static DecodedJWT verify(String token) {//如果有任何验证异常,此处都会抛出异常return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);}/*** 获取token中的payload*/public static Map<String, Claim> getPayloadFromToken(String token) {return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token).getClaims();}
}

2.3 写个mybatis的mapper.xml和dao

mapper.xml

    <select id="login" parameterType="User" resultType="User">select * from user2 where name = #{name} and password = #{password}</select>
@Mapper
public interface UserDao {User login(User user); // 直接根据用户名密码进行登录
}

2.4 实现类

service

public interface UserService {User login(User user); // 登录接口
}

impl

@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserDao userDao;@Override@Transactional(propagation = Propagation.SUPPORTS)public User login(User user) {User login = userDao.login(user); // 根据用户名和密码if (login != null) {return login;}throw new RuntimeException("登录失败...");}
}

2.5 控制层


@RestController
@Slf4j
public class UserController {@Resourceprivate UserService userService;@GetMapping("/user/login")public Map<String, Object> login(User user){log.info(user.getName());log.info(user.getPassword());Map<String, Object> map = new HashMap<>();try{User login = userService.login(user);Map<String, String> payload = new HashMap<>();payload.put("id", String.valueOf(login.getId()));payload.put("name", login.getName());payload.put("password", login.getPassword());// 生成tokenString token = JWTUtil.getToken(payload);map.put("status", true);map.put("msg", "登录成功");map.put("token", token); // 响应token,存储在客户端}catch (Exception e) {log.info("登录失败...");map.put("status", false);map.put("msg", "登录失败");}return map;}@PostMapping("/user/test")public Map<String, Object> test(HttpServletRequest request) {String token = request.getHeader("token");DecodedJWT verify = JWTUtil.verify(token);String id = verify.getClaim("id").asString(); // 我前面存的时候转字符串了String name = verify.getClaim("name").asString();log.info("用户id:{}", id);log.info("用户名: {}", name);//TODO:业务逻辑Map<String, Object> map = new HashMap<>();map.put("status", true);map.put("msg", "请求成功");return map;}}

2.6 拦截器

@Slf4j
public class JWTInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {//获取请求头中的令牌String token = request.getHeader("token");log.info("当前token为:{}", token);Map<String, Object> map = new HashMap<>();try {JWTUtil.verify(token);return true;} catch (SignatureVerificationException e) {e.printStackTrace();map.put("msg", "签名不一致");} catch (TokenExpiredException e) {e.printStackTrace();map.put("msg", "令牌过期");} catch (AlgorithmMismatchException e) {e.printStackTrace();map.put("msg", "算法不匹配");} catch (InvalidClaimException e) {e.printStackTrace();map.put("msg", "失效的payload");} catch (Exception e) {e.printStackTrace();map.put("msg", "token无效");}map.put("status", false);//响应到前台: 将map转为jsonString json = new ObjectMapper().writeValueAsString(map);response.setContentType("application/json;charset=UTF-8");response.getWriter().println(json);return false;}
}

2.7 postman测试

 

 


http://www.ppmy.cn/news/43020.html

相关文章

webgl-画一个彩色矩形

html <!DOCTYPE html> <head> <style> *{ margin: 0px; padding: 0px; } </style> </head> <body> <canvas id webgl> 您的浏览器不支持HTML5,请更换浏览器 </canvas> <script src"./main.js"></script&g…

SDUT操作系统课程(CAST)专题二+专题四参考总结

专题二+进程调度算法 RR q=1(含做题代码) 总结:到达时间一到对应进程进入,执行队首进程一次,对应的服务时间划一记号(推荐用正字),队首进程未执行到完成的话重新进入队尾,队首进程执行到完成的话出队,下一秒继续执行队首进程,当5个进程全部入队之后只要执行后两步操…

更新按日期分表,多个表添加字段

更新日志表 SET sql ‘’; SELECT GROUP_CONCAT(CONCAT(‘ALTER TABLE , table_name, ADD COLUMN result_total bigint(20) NULL DEFAULT 0 COMMENT “接口返回数据量”;’) SEPARATOR ’ ) INTO sql FROM information_schema.tables WHERE table_name LIKE ‘t_dg_service_…

九龙证券|这一刻,资本市场进入全新时代!

2023年4月10日&#xff0c;第一批10家主板注册制企业上市鸣锣敲钟&#xff0c;奏响了触及本钱商场灵魂深处革新的序曲。 动能切换中的我国对于高效资源配置的渴望&#xff0c;与革新进行时的本钱商场对于全面注册制的探究&#xff0c;一起凝集成一股连绵有力之暖流&#xff0c;…

数据一致性校验(pt-table-checksum)

介绍 pt-table-checksum 和 pt-table-sync 是 percona 公司发布的、检查 MySQL 主从数据库数据一致性校验的工具。pt-table-checksum 利用 MySQL 复制原理&#xff0c;在主库执行校验和计算&#xff0c;并对比主从库校验和&#xff0c;由此判断主从库数据是否一致。如果发现数…

ChatGPT热潮下,因生成式AI失业的人出现,我成了第一批失业的人

近几个月来&#xff0c;越来越多的知名人士预计&#xff0c;年内大热的ChatGPT有望掀起一场新的工业革命。而纵观历史&#xff0c;历次工业革命往往会深远改变当时的社会结构——从机械织布机到内燃机再到第一台计算机&#xff0c;新技术的出现总是会引起人们对于被机器取代的恐…

博弈论在电动车和电网系统中分布式模型预测控制研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

微软 AI 作图上线完全免费,“奖励自己”可提升速度

ChatGPT 的横空出世应该已经让大家意识到了 AI 的恐怖。 称不上啥都能干&#xff0c;但给东西它真学&#xff0c;学得还比你快。 最近一段时间 AI 在作图领域又一次人气暴涨。 什么小姐姐写真、突破时间线的历史古图、甚至是抽象的表情包都可能源于 AI 之手。 看着手痒想玩玩…