中间件学习-jwt登录验证
jwt
json web token
简要说明
前端传验证信息到后端,后端验证通过,返回一个对象,只不过这个对象是被加密的,这样后端就可以为无状态的,每次请求的时候,请求头带上token ,里面封装了对象的信息,我们只需要用拦截器进行拦截,解析token,后端就可以知道是谁登录了界面,可以设置相应的超时时间,超时时间不应太长或者太短,根据实际情况而定,超时用户就需要从新登录
优点: 减少服务器的压力,不用向以前一样将对象保存在session里面,或者是利用redis保存信息,因为redis也是要占用服务器的内存的。
非常适合springcloud 微服务
示例
校验token
拦截器代码
public class AuthenticationInterceptor implements HandlerInterceptor {
@Autowired
UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//进入方法之前进行的操作
//获取token
String token = request.getHeader("token");
//如果不是映射到方法直接通过
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
if (method.isAnnotationPresent(PassToken.class)) {
PassToken passToken = method.getAnnotation(PassToken.class);
if (passToken.required()) {
return true;
}
}
String userId = null;
if (method.isAnnotationPresent(UserLoginToken.class)) {
UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
if (userLoginToken.required()) {
if (token == null) {
throw new RuntimeException("无token,请重新登录");
}
//获取token的userid
try {
userId = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException e) {
throw new RuntimeException("401");
}
User user = userService.getUser(userId);
if (user == null) {
throw new RuntimeException("用户不存在");
}
//验证token
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token);
} catch (JWTVerificationException e) {
throw new RuntimeException("401");
}
return true;
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//方法处理之后但是并未渲染视图的时候进行的操作
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//渲染视图之后进行的操作
}
}
jwtVerifier.verify(token)
//这句代码校验token是否正确
public DecodedJWT verify(String token) throws JWTVerificationException {
DecodedJWT jwt = JWT.decode(token);
this.verifyAlgorithm(jwt, this.algorithm);
this.algorithm.verify(jwt);
this.verifyClaims(jwt, this.claims);
return jwt;
}
token颁发
获取User及PassWord
User userforbase = userService.getUserByName(user.getUsername());
if(userforbase==null){
return JSONResultUtils.errorMsg("登录失败,用户不存在");
}
if(!userforbase.getPassword().equals(user.getPassword())){
return JSONResultUtils.errorMsg("登录失败,密码错误");
}
String token = TokenUtil.getToken(userforbase);
return token;
通过getToken方法生成
public class TokenUtil {
public static String getToken(User user){
String token = "";
token = JWT.create().withAudience(user.getId())
.sign(Algorithm.HMAC256(user.getPassword()));
return token;
}
}
效果演示
原文
https://blog.csdn.net/qq_37992974/article/details/90236581
补充
原文缺少JSONResultUtils类代码如下
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import java.util.List;
public class JSONResultUtils {
protected static final Integer FAIL_CODE = 1;
protected static final Integer SUCCESS_CODE = 0;
//响应吗
protected Integer code;
//响应信息
protected String message;
//响应数据
protected Object data;
@Override
public String toString() {
return "EasyCityJsonResult [code=" + code + ", message=" + message + ", data=" + data + "]";
}
public static String ok(Object object) {
JSONObject json = JSONUtil.createObj();
JSONObject json_list =JSONUtil.createObj();
if(object instanceof List || object.getClass().isArray()) {
json_list.put("list", object);
json.put("code", SUCCESS_CODE);
json.put("data", json_list);
return json.toString();
}else {
json.put("code", SUCCESS_CODE);
json.put("data", object);
return json.toString();
}
}
public static String errorMsg(Object object) {
JSONObject json =JSONUtil.createObj();
json.put("code", FAIL_CODE);
json.put("data", object);
return json.toString();
}
}