目前传统的后台管理系统,以及不使用第三方登录的系统,使用 JWT 技术的还是挺多的,因此在面试中被问到的频率也比较高,所以今天我们就来看一下:什么是 JWT?为什么要用 JWT?
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络上安全传输信息的简洁、自包含的方式。它通常被用于身份验证和授权机制。JWT 由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。
“
JWT 官网:https://jwt.io/
”
JWT 相较于传统的基于会话(Session)的认证机制,具有以下优势:
总结来说,使用 JWT 相较于传统的基于会话的认证机制,可以减少服务器存储开销和管理复杂性,实现跨域支持和水平扩展,并且更适应无状态和微服务架构。
在 Java 开发中,可以借助 JWT 工具类来方便的操作 JWT,例如 HuTool 框架中的 JWTUtil。
HuTool 介绍:https://doc.hutool.cn/pages/JWTUtil/
使用 HuTool 操作 JWT 的步骤如下:
在 pom.xml 中添加以下信息:
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version></dependency>
Map<String, Object> map = new HashMap<String, Object>() {private static final long serialVersionUID = 1L;{ put("uid", Integer.parseInt("123")); // 用户ID put("expire_time", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 15); // 过期时间15天}};JWTUtil.createToken(map, "服务器端秘钥".getBytes());
验证 Token 的示例代码如下:
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE2MjQwMDQ4MjIsInVzZXJJZCI6MSwiYXV0aG9yaXRpZXMiOlsiUk9MRV_op5LoibLkuozlj7ciLCJzeXNfbWVudV8xIiwiUk9MRV_op5LoibLkuIDlj7ciLCJzeXNfbWVudV8yIl0sImp0aSI6ImQ0YzVlYjgwLTA5ZTctNGU0ZC1hZTg3LTVkNGI5M2FhNmFiNiIsImNsaWVudF9pZCI6ImhhbmR5LXNob3AifQ.aixF1eKlAKS_k3ynFnStE7-IRGiD5YaqznvK2xEjBew";JWTUtil.verify(token, "123456".getBytes());
解析 Token 的示例代码如下:
String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9.U2aQkC2THYV9L0fTN-yBBI7gmo5xhmvMhATtu8v0zEA";final JWT jwt = JWTUtil.parseToken(rightToken);jwt.getHeader(JWTHeader.TYPE);jwt.getPayload("sub");
在登录成功之后,生成 Token 的示例代码如下:
// 登录成功,使用 JWT 生成 TokenMap<String, Object> payload = new HashMap<String, Object>() { private static final long serialVersionUID = 1L; { put("uid", userinfo.getUid()); put("manager", userinfo.getManager()); // JWT 过期时间为 15 天 put("exp", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 15); }};String token = JWTUtil.createToken(payload, AppVariable.JWT_KEY.getBytes());
例如在 Spring Cloud Gateway 网关中验证 Token 的实现代码如下:
import cn.hutool.jwt.JWT;import cn.hutool.jwt.JWTUtil;import com.example.common.AppVariable;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.Ordered;import org.springframework.http.HttpStatus;import org.springframework.http.server.reactive.ServerHttpResponse;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;import java.util.List;/** * 登录过滤器(登录判断) */@Componentpublic class AuthFilter implements GlobalFilter, Ordered { // 排除登录验证的 URL 地址 private String[] skipAuthUrls = {"/user/add", "/user/login"}; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 当前请求的 URL String url = exchange.getRequest().getURI().getPath(); for (String item : skipAuthUrls) { if (item.equals(url)) { // 继续往下走 return chain.filter(exchange); } } ServerHttpResponse response = exchange.getResponse(); // 登录判断 List<String> tokens = exchange.getRequest().getHeaders().get(AppVariable.TOKEN_KEY); if (tokens == null || tokens.size() == 0) { // 当前未登录 response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } // token 有值 String token = tokens.get(0); // JWT 效验 token 是否有效 boolean result = false; try { result = JWTUtil.verify(token, AppVariable.JWT_KEY.getBytes()); } catch (Exception e) { result = false; } if (!result) { // 无效 token response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } else { // 判断 token 是否过期 final JWT jwt = JWTUtil.parseToken(token); // 得到过期时间 Object expObj = jwt.getPayload("exp"); if (expObj == null) { response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } long exp = Long.parseLong(expObj.toString()); if (System.currentTimeMillis() > exp) { // token 过期 response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } } return chain.filter(exchange); } @Override public int getOrder() { // 值越小越早执行 return 1; }}
JWT 本质是将秘钥存放在服务器端,并通过某种加密手段进行加密和验证的机制。加密签名=某加密算法(header+payload+服务器端私钥),因为服务端私钥别人不能获取,所以 JWT 能保证自身其安全性。
JWT 相比与传统的 Session 会话机制,具备无状态性(无需服务器端存储会话信息),并且它更加灵活、更适合微服务环境下的登录和授权判断。JWT 是由三部分组成的:Header(头部)、Payload(数据载荷)和 Signature(签名)。
本文链接:http://www.28at.com/showinfo-26-38494-0.html面试官:什么是JWT?为什么要用JWT?
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: 面试官:什么是JWT?为什么要用JWT?