JWT配置
HTTPResponse.java
package xyz.nieqiang.webapp.util;
public class HTTPResponse {
private Integer status;
private String message;
private Object data;
public static HTTPResponse ok(String message) {
return new HTTPResponse(200, message);
}
public static HTTPResponse ok(Object data) {
return new HTTPResponse(200, data);
}
public static HTTPResponse ok(String message,Object data) {
return new HTTPResponse(200, message, data);
}
public static HTTPResponse error(Integer status, String message) {
return new HTTPResponse(500, message, null);
}
public static HTTPResponse error(String message) {
return new HTTPResponse(500, message, null);
}
public static HTTPResponse error(String message,Object data) {
return new HTTPResponse(500, message, data);
}
protected HTTPResponse() {super();}
private HTTPResponse(Integer status, String message) {
this.status = status;
this.message = message;
}
private HTTPResponse(Integer status, Object data) {
this.status = status;
this.data = data;
}
private HTTPResponse(Integer status, String message, Object data) {
this.status = status;
this.message = message;
this.data = data;
}
public Integer getStatus() {return status;}
public String getMessage() {return message;}
public Object getData() {return data;}
public void setStatus(Integer status) {this.status = status;}
public void setMessage(String message) {this.message = message;}
public void setObject(Object data) {this.data = data;}
}
JWTConfiguration.java
package xyz.nieqiang.webapp.configuration;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import xyz.nieqiang.webapp.util.HTTPResponse;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
@Component
public class JWTConfiguration implements HandlerInterceptor {
private final static Logger logger = LoggerFactory.getLogger(JWTConfiguration.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 如果cookie不为空
if (request.getHeader("Cookie") != null) {
try {
JwtParser parser = Jwts.parser();
// 加密盐值
parser.setSigningKey("liangzhun-@20200805");
// 解析token
Cookie[] cookies = request.getCookies();
String CookieToken = null;
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals("token")) {
CookieToken = cookies[i].getValue();
}
}
Jws<Claims> claimsJws = parser.parseClaimsJws(CookieToken);
// token有效期7天,如果有效期小于3天,置为7天
if (Integer.parseInt(claimsJws.getBody().get("exp").toString()) - System.currentTimeMillis() / 1000 < 60 * 60 * 24 * 3) {
logger.info("token续签!!!");
String token = Jwts.builder().setSubject(claimsJws.getBody().getSubject()).setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 29 * 24 * 60 * 60 * 1000))
.signWith(SignatureAlgorithm.HS256, "liangzhun-@20200805").compact();
// set cookie到前端
Cookie cookie = new Cookie("token", token);
cookie.setPath("/");
cookie.setMaxAge(60 * 60 * 24 * 10);
response.addCookie(cookie);
}
// 解析成功拦截器放行
return true;
// 抛异常token解析失败
} catch (ExpiredJwtException e) {// token过期
logger.info("token过期");
response.setContentType("application/json;charset=UTF-8");
response.setStatus(401);
PrintWriter printWriter = response.getWriter();
HTTPResponse httpResponse = HTTPResponse.error("用户身份过期", 401);
String s = new ObjectMapper().writeValueAsString(httpResponse);
printWriter.write(s);
printWriter.flush();
printWriter.close();
return false;
} catch (Exception e) {
logger.info("token错误");
response.setContentType("application/json;charset=UTF-8");
PrintWriter printWriter = response.getWriter();
HTTPResponse httpResponse = HTTPResponse.error("用户身份错误", 403);
String s = new ObjectMapper().writeValueAsString(httpResponse);
printWriter.write(s);
printWriter.flush();
printWriter.close();
return false;
}
} else {
logger.info("token is null");
response.setContentType("application/json;charset=UTF-8");
PrintWriter printWriter = response.getWriter();
HTTPResponse httpResponse = HTTPResponse.error("token is null", 403);
String s = new ObjectMapper().writeValueAsString(httpResponse);
printWriter.write(s);
printWriter.flush();
printWriter.close();
return false;
}
}
}
JWTFilterConfig.java
package xyz.nieqiang.webapp.configuration;
import javax.annotation.Resource;
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 JWTFilterConfig implements WebMvcConfigurer {
@Resource
private JWTConfiguration jWTConfiguration;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jWTConfiguration)
.addPathPatterns("/**")//拦截所有接口
.excludePathPatterns("/login");//不拦截/login接口
}
}
LoginController.java
package xyz.nieqiang.webapp.controller;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import xyz.nieqiang.webapp.entity.User;
import xyz.nieqiang.webapp.util.HTTPResponse;
@RestController
public class LoginController {
private static final Logger logger = LoggerFactory.getLogger(LoginController.class);
@PostMapping("/login")
public HTTPResponse login(String username, String password, HttpServletResponse response) {
User user = new User();
user.setId(111);
user.setUsername("liangzhun");
user.setPassword("liangzhun@4399");
logger.info("{}```{}```{}```{}",username,user.getUsername(),password,user.getPassword());
if(!(user.getUsername().equals(username) && user.getPassword().equals(password))) {
return HTTPResponse.error("用户名或密码错误!","");
}
//存放用户信息
Map<String, String> map = new HashMap<String , String>();
map.put("id", user.getId().toString());
map.put("username", user.getUsername());
String token = Jwts.builder()
//存放用户信息
.setSubject(map.toString())
//设置当前是时间
.setIssuedAt(new Date())
//设置到期时间,7天
.setExpiration(new Date(System.currentTimeMillis()+7*24*60*60*1000))
//.setExpiration(new Date(System.currentTimeMillis()-10*24*60*60*1000))
//加密加盐
.signWith(SignatureAlgorithm.HS256,"liangzhun-@20200805")
.compact();;
//set cookie到前端
Cookie cookie = new Cookie("token",token);
cookie.setPath("/");
cookie.setMaxAge(24*60*60*1000*3);
response.addCookie(cookie);
user.setPassword(null);
return HTTPResponse.ok("登录成功!");
}
}
踩坑
坑:页面刷新存在token过期的问题
踩:检查token设置最大时间是否与续签时间长度相冲突,比如设置的最大有效时间为3天,请求时校验token时间不满5天就续签,这里肯定是相冲突的,要改成小于有效时间的天数