黑马程序员day12)"/>
SpringBoot学习(黑马程序员day12)
1jwt令牌
JWT的组成: (JWT令牌由三个部分组成,三个部分之间使用英文的点来分割)
第一部分:Header(头), 记录令牌类型、签名算法等。 例如:
{"alg":"HS256","type":"JWT"}
第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:
{"id":"1","username":"Tom"}
第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加
入指定秘钥,通过指定签名算法计算而来。
1.1jwt令牌的生成:
1.1.1添加依赖:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
@Test
public void genJwt(){
Map<String,Object> claims = new HashMap<>();
claims.put("id",1);
claims.put("username","Tom");
String jwt = Jwts.builder().setClaims(claims) //自定义内容(载荷) .signWith(SignatureAlgorithm.HS256, "itheima") //签名算法.setExpiration(new Date(System.currentTimeMillis() +
24*3600*1000)) //有效期pact();
System.out.println(jwt);
}
1.2jwt令牌的校验:
@Testpublic void parseJwt() {Claims claims = Jwts.parser().setSigningKey("itheima")//指定签名密钥(必须保证和生成令牌时使用 相同的签名密钥).parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiamlueW9uZyIsImlkIjoxLCJleHAiOjE2OTk1MTU4MzV9.fE2BfR6WlmlnrFdCeHsvfTMKdo623Sg5FDf3Ql5mi9Q").getBody();System.out.println(claims);}
JWT校验时使用的签名秘钥,必须和生成JWT令牌时使用的秘钥是配套的。
如果JWT令牌解析校验时报错,则说明 JWT令牌被篡改 或 失效了,令牌非法。
1.3服务端响应客户端jwt令牌:
1.3.1 生成jwt的工具类:
public class JwtUtil {private static String signKey = "itheima";//签名密钥private static Long expire = 43200000L; //有效时间public static String generateJwt(Map<String, Object> claims) {String jwt = Jwts.builder().addClaims(claims)//自定义信息(有效载荷).signWith(SignatureAlgorithm.HS256, signKey).setExpiration(new Date(System.currentTimeMillis() +expire))//过期时间pact();return jwt;}/*** 解析JWT令牌* @param jwt JWT令牌* @return JWT第二部分负载 payload 中存储的内容*/public static Claims parseJWT(String jwt){Claims claims = Jwts.parser().setSigningKey(signKey)//指定签名密钥.parseClaimsJws(jwt)//指定令牌Token.getBody();return claims;}
}
1.3.2在登录控制类中实现:
public Result loginByName(@RequestBody Emp emp) {log.info("用户登录功能");Emp emp1 = loginService.loginByName(emp);if (emp1 != null) {Map<String, Object> stringObjectMap = new HashMap<>();stringObjectMap.put("id", 1);stringObjectMap.put("name", "jinyong");String jwt = JwtUtil.generateJwt(stringObjectMap);return Result.success(jwt);} else {return Result.success("登录失败");}}
2 过滤器Filter
2.1实现步骤:
第1步,定义过滤器 :1.定义一个类,实现 Filter 接口,并重写其所有方法。
第2步,配置过滤器:Filter类上加 @WebFilter 注解,配置拦截资源的路径。引导类上加
@ServletComponentScan 开启Servlet组件支持。
实现类:
package com.heima.Filter;import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import org.springframework.context.annotation.ComponentScan;import java.io.IOException;@WebFilter(urlPatterns = "/*")
public class Filter1 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);System.out.println("生成了一个过滤器");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("过滤器放行");filterChain.doFilter(servletRequest,servletResponse);}@Overridepublic void destroy() {Filter.super.destroy();System.out.println("销毁了过滤器");}
}
2.2过滤器的拦截路径:
设置方式,例如:@WebFilter(urlPatterns = "/*")
2.3实现登录的拦截:
@Slf4j
@WebFilter(urlPatterns = "/*") //拦截所有请求
public class LoginCheckFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest,ServletResponse servletResponse, FilterChain chain) throwsIOException, ServletException {
//前置:强制转换为http协议的请求对象、响应对象 (转换原因:要使用子类中特有方法)HttpServletRequest request = (HttpServletRequest)servletRequest;HttpServletResponse response = (HttpServletResponse)servletResponse;
//1.获取请求urlString url = request.getRequestURL().toString();log.info("请求路径:{}", url);if(url.contains("/login")){chain.doFilter(request, response);//放行请求return;//结束当前方法的执行}
//3.获取请求头中的令牌(token)String token = request.getHeader("token");log.info("从请求头中获取的令牌:{}",token);
//4.判断令牌是否存在,如果不存在,返回错误结果(未登录)if(!StringUtils.hasLength(token)){log.info("Token不存在");Result responseResult = Result.error("NOT_LOGIN");//没有Restrequest注解不能自动转为json格式的数据
//把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)String json = JSONObject.toJSONString(responseResult);response.setContentType("application/json;charset=utf-8");//响应response.getWriter().write(json);return;}
//5.解析token,如果解析失败,返回错误结果(未登录)try {JwtUtil.parseJWT(token);}catch (Exception e){log.info("令牌解析失败!");Result responseResult = Result.error("NOT_LOGIN");
//把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)String json = JSONObject.toJSONString(responseResult);response.setContentType("application/json;charset=utf-8");
//响应response.getWriter().write(json);return;}
//6.放行chain.doFilter(request, response);}
}
需要导入aliyun的json依赖:
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency>
更多推荐
SpringBoot学习(黑马程序员day12)
发布评论