在up主青戈视频中提到了后端jwt加密,如果你想学习如何使用jwt进行加密的话,在下建议你去看看青戈的视频,以下是我在看第16个视频所做的学习笔记,希望对你们有帮助!
一、认识JWT
Jwt全称是:json web token。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。
优点
- 简洁: 可以通过URL、POST参数或者在HTTP header发送,因为数据量小,传输速度也很快;
- 自包含:负载中可以包含用户所需要的信息,避免了多次查询数据库;
- 因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持;
- 不需要在服务端保存会话信息,特别适用于分布式微服务。
缺点
- 无法作废已颁布的令牌;
- 不易应对数据过期。
二、springboot集成JWT
- 添加jwt依赖
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.10.3</version> </dependency>
- 创建TokenUtils文件
package com.example.huotaiguanli.utils; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.example.huotaiguanli.entity.User; import com.example.huotaiguanli.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.Date; @Component public class TokenUtils { private static IUserService staticUserService; @Resource private IUserService userService; @PostConstruct public void setUserService(){ staticUserService = userService; } /** * 生成token * */ public static String genToken(String userId,String sign){ return JWT.create().withAudience(userId) // 将 user id 保存到 token 里面 .withExpiresAt(DateUtil.offsetHour(new Date(),2)) //五分钟后token过期 .sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥 } /** *获取当前登录的用户信息 * */ public static User getCurrentUser(){ try{ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String token = request.getHeader("token"); if(StrUtil.isNotBlank(token)) { String userId = JWT.decode(token).getAudience().get(0); return staticUserService.getById(Integer.valueOf(userId)); } } catch (Exception e) { return null; } return null; } }
- 设置token
- 页面效果
- 前端登录拿到token放在请求头里带给后台,后台拿到请求后进行验证,验证合不合法
- 拦截器验证token
package com.example.huotaiguanli.config.interceptor; import cn.hutool.core.util.StrUtil; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTDecodeException; import com.auth0.jwt.exceptions.JWTVerificationException; import com.example.huotaiguanli.common.Constants; import com.example.huotaiguanli.entity.User; import com.example.huotaiguanli.exception.ServiceException; import com.example.huotaiguanli.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class JwtInterceptor implements HandlerInterceptor { @Autowired private IUserService userService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token= request.getHeader("token"); //如果不是映射到方法直接通过 if(!(handler instanceof HandlerMethod)){ return true; } // 执行认证 if (StrUtil.isBlank(token)) { throw new ServiceException( Constants.CODE_401,"无token,请重新登录") ; } // 获取 token 中的 user id String userId; try { userId = JWT.decode(token).getAudience().get(0); } catch (JWTDecodeException j) { throw new ServiceException(Constants.CODE_401, "token验证失败,请重新登录"); } //根据token中的userid查询数据库 User user = userService.getById(userId); if (user == null) { throw new ServiceException(Constants.CODE_401, "用户不存在,请重新登录"); } // 用户密码加签验证 token JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build(); try { jwtVerifier.verify(token); //验证token } catch (JWTVerificationException e) { throw new ServiceException(Constants.CODE_401, "token验证失败,请重新登录"); } return true; } }
- 创建InterceptorConfig类
package com.example.huotaiguanli.config; import com.example.huotaiguanli.config.interceptor.JwtInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtInterceptor()) .addPathPatterns("/**") //拦截所有请求,通过判断token 是否合法来决定是否需要登录 .excludePathPatterns("/user/login","/user/register","/**/export","/**/import"); } @Bean public JwtInterceptor jwtInterceptor(){ return new JwtInterceptor(); } }
- 出现空指针异常
分析原因:userservice是空值
解决方法:
- 前端设置当权限不通过时给予提示
当直接输入localhost:8080/user时,系统会提示你:
- 后台想获取当前用户的信息应该通过下面方式去获取
三、总结
以上就是我所整理的学习笔记,我们下期再见!