一 要使用JWT做用户登录验证, 首先要引入 JwtUtil工具类, 其中包含了生成jwt与解密jwt的函数
```java utils.JwtUtil 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public class JwtUtil {
public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) { SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long expMillis = System.currentTimeMillis() + ttlMillis; Date exp = new Date(expMillis);
JwtBuilder builder = Jwts.builder() .setClaims(claims) .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8)) .setExpiration(exp);
return builder.compact(); }
public static Claims parseJWT(String secretKey, String token) { Claims claims = Jwts.parser() .setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8)) .parseClaimsJws(token).getBody(); return claims; }
}
|
二 在application中先对jwt所需的参数进行设置, 然后通过注入的方式赋值给实体类JwtProperties.java, 以供后期使用
```yml application.yml 中
1 2 3 4 5 6 7 8 9
| work: jwt: admin-secret-key: itcast admin-ttl: 7200000 admin-token-name: token
|
```java properties.JwtProperties.java 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Component @ConfigurationProperties(prefix = "work.jwt") @Data public class JwtProperties {
private String adminSecretKey; private long adminTtl; private String adminTokenName;
private String userSecretKey; private long userTtl; private String userTokenName;
}
|
三 创建JwtTokenadminInterceptor拦截器, 随后将其加入配置文件WebMvcConfiguration中,它可以拦截指定的请求头从中获取到token
```java interceptor.JwtTokenAdminInterceptor.java 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| @Component @Slf4j public class JwtTokenAdminInterceptor implements HandlerInterceptor {
@Autowired private JwtProperties jwtProperties;
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (!(handler instanceof HandlerMethod)) { return true; }
String token = request.getHeader(jwtProperties.getAdminTokenName());
try { log.info("jwt校验:{}", token); Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token); Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString()); log.info("当前员工id:", empId); BaseContext.setCurrentId(empId); return true; } catch (Exception ex) { response.setStatus(401); return false; } } }
|
```java WebMvcConfiguration.java 中
1 2 3 4 5 6 7 8 9 10 11
|
protected void addInterceptors(InterceptorRegistry registry) { log.info("开始注册自定义拦截器..."); registry.addInterceptor(jwtTokenAdminInterceptor) .addPathPatterns("/admin/**") .excludePathPatterns("/admin/employee/login"); }
|
四 现在可以在登录的方法中,配置第一次登录时生成jwt的方法
```java controller.loginController.java *login()中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| @Autowired private JwtProperties jwtProperties;
@PostMapping("/login") @ApiOperation("员工登录") public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) { log.info("员工登录:{}", employeeLoginDTO);
Employee employee = employeeService.login(employeeLoginDTO);
Map<String, Object> claims = new HashMap<>(); claims.put(JwtClaimsConstant.EMP_ID, employee.getId()); String token = JwtUtil.createJWT( jwtProperties.getAdminSecretKey(), jwtProperties.getAdminTtl(), claims);
EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder() .id(employee.getId()) .userName(employee.getUsername()) .name(employee.getName()) .token(token) .build();
return Result.success(employeeLoginVO); }
|
到此 jwt登录检测完成, 后续检查jwt业务由配置类文件拦截路径后, 经过JwtTokenadminInterceptor拦截器检验决定是否放行