1. 引入依赖
使用hutool依赖来操作jwt;lombok来记日志
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.13</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--日志依赖-->
<dependency>
<!--用于注解 @Slf4j中,-->
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
2. 添加配置
在application.yml中添加jwt 的秘钥,以及过期时间,
secretKey:秘钥
expireSeconds:过期时间,10分钟
jwt:
secretKey: KxK7f3yaSfOXVwvuYJDozvQ7Mt1JnqRX
expireSeconds: 10
3. 编写JwtUtil 工具类
package com.manager.oa.util.security;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @Author sms
* @Version V1.0.0
* @Date 2022-08-09
*/
@Component
@Slf4j
public class JwtUtil {
// 秘钥
@Value("${jwt.secretKey}")
private String secretKey;
// 过期时间
@Value("${jwt.expireSeconds}")
private String expireSeconds;
{
log.debug("【jwtUtil】secretKey->{}",secretKey);
}
/**
* 产生Token
*
* @param map 需要载荷的数据 map类
* @return
*/
public String createJWT(Map<String, Object> map) {
//当前时间
DateTime now = DateTime.now();
// 设置过期时间
DateTime newTime = now.offsetNew(DateField.MINUTE, Integer.parseInt(expireSeconds));
Map<String, Object> payload = new HashMap<String, Object>();
//签发时间
payload.put(JWTPayload.ISSUED_AT, now);
//过期时间
payload.put(JWTPayload.EXPIRES_AT, newTime);
//生效时间
payload.put(JWTPayload.NOT_BEFORE, now);
//载荷
Set<String> keySet = map.keySet();
for (String key : keySet
) {
payload.put(key, map.get(key));
}
// 产生Token
return JWTUtil.createToken(payload, secretKey.getBytes());
}
/**
* 验证
*
* @param token
* @return
*/
public boolean verifyJWT(String token) {
JWT jwt = JWTUtil.parseToken(token);
boolean verifyKey = jwt.setKey(secretKey.getBytes()).verify();
return verifyKey;
}
/**
* 验证时间是否过期
*
* @param token
* @return
*/
public boolean verifyTimeJWT(String token) {
try {
JWTValidator.of(token).validateDate(DateUtil.date());
return true;
} catch (ValidateException e) {
e.printStackTrace();
return false;
}
}
}
4. 添加filter校验
1)编写TokenFilter
package com.manager.oa.filter;
import com.manager.oa.util.security.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @Author sms
* @Version V1.0.0
* @Date 2022-08-10
*/
@Slf4j
public class TokenFilter implements Filter {
@Autowired
private JwtUtil jwtUtil;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.debug("【过滤器】:进入到token验证过滤器-》");
/*
token验证
*/
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
log.debug("【filter】uri->{}", httpServletRequest.getRequestURI());
// 放行登录请求
if (httpServletRequest.getRequestURI().equals("/login")) {
chain.doFilter(httpServletRequest, response);
} else {
String token = httpServletRequest.getHeader("X-Token");
log.debug("【filter】验证token...->{}", token);
log.debug("【filter】jwtUtil->{}", jwtUtil);
if (jwtUtil.verifyJWT(token)) {
chain.doFilter(httpServletRequest, response);
}
}
}
@Override
public void destroy() {
}
}
2)将TokenFilter交给spring管理
在Application中添加配置
// token校验过滤器
@Bean
public FilterRegistrationBean myTokenFilterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
// 不能new 需要交给spring管理后,单独写方法调用 ,否则为null
filterRegistrationBean.setFilter(this.TokenExpireFilter());
// 添加过滤路径
filterRegistrationBean.addUrlPatterns("/*");
// 保证在所有过滤之前执行
filterRegistrationBean.setOrder(1);
return filterRegistrationBean;
}
@Bean
public Filter TokenExpireFilter() {
return new TokenFilter();
}
5. 测试
login
@PostMapping("/login")
public ResponseEntity<?> doLogin(@RequestBody User user) {
log.debug("【系统日志】:->正在登录;携带的参数:{}", user);
user.setPassword(DigestUtils.md5Hex(user.getPassword()));
User DBUser = userService.getUserByLogin(user);
if (DBUser == null) {
log.debug("【系统日志】:{}->登录失败;", user.getAccount());
return new ResponseEntity<>(false, "500", "账号或密码错误", null);
} else {
log.debug("【系统日志】:{}->登录成功;", user.getAccount());
Map<String, Object> map = new HashMap<>();
map.put("account", DBUser.getAccount());
map.put("id", DBUser.getId());
String token = jwtUtil.createJWT(map);
log.debug("【系统日志】Token->{}", token);
return new ResponseEntity<>(token);
}
}
@RequestMapping("/")
public ResponseEntity<List<Menu>> getIndex(HttpServletRequest request) {
String token = request.getHeader("X-Token");
log.debug("【系统日志】进入到首页, 前端返回的token->{}", token);
JWT jwt = JWTUtil.parseToken(token);
// jwt.getPayload("id")取出数据
User DBUser = userService.getById((Integer) jwt.getPayload("id"));
List<Menu> menuList = new ArrayList<>();
return new ResponseEntity<>(menuList);
}