package com.example.demo.test; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Objects; public class LoginInterceptor implements HandlerInterceptor { @Autowired private RedisService redis; @Autowired private UserService userService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { String tokenName = "Authorization"; // 尝试从header中取token String token = request.getHeader(tokenName); //尝试从参数中取token if (StrUtil.isEmpty(token)) { token = request.getParameter(tokenName); } //尝试从cooke if (StrUtil.isEmpty(token)) { cookie[] cookies = request.getcookies(); for (cookie cookie : cookies) { if (Objects.equals(cookie.getName(), tokenName)) { token = cookie.getValue(); } } } //如果前端没有携带token返回json数据 if (StrUtil.isBlank(token)) { PrintWriter pw = response.getWriter(); pw.write(JSON.toJSonString("用户未登录")); return false; } //解析token String jwtId = JwtTool.checkJwtToken(token); if (jwtId == null) { throw new ServiceException(401, "用户未登录"); } //获取用户ID String tokenUserId = JwtTool.getUserId(token); //token存在,但是redis不存在。要么是失效,要么是强制下线 JwtInfo jwt = redis.get(RedisKey.getToken(tokenUserId, jwtId)); if (jwt == null || !jwt.getToken().equals(token)) { throw new ServiceException(401, "您当前登录的账号已失效,请重新登录"); } //获取用户ID Long userId = jwt.getUserId(); //查询用户 User user = userService.selectById(userId); //判断用户是否存在 if (user == null) { throw new ServiceException(MsgCode.CODE_UNAUTHORIZED, "用户不存在"); } //根据业务需求增加其他判断条件 if (user.getStatus() == 1) { throw new ServiceException(MsgCode.CODE_UNAUTHORIZED, "用户已禁用!"); } //将登录用户放到ThreadLocal变量变量中,方便业务获取当前登录用户 CurrentUser currentUser = new CurrentUser(); currentUser.setId(userId); currentUser.setUserName(user.getAccountname()); currentUser.setNickName(user.getName()); //当前用户放到ThreadLocal变量变量中 CurrentUserUtil.set(currentUser); return true; } }
涉及其他类
public class CurrentUserUtil { private CurrentUserUtil() { } private static final ThreadLocalCURRENT_USER = new ThreadLocal (); public static void set(CurrentUser currentUser) { CURRENT_USER.set(currentUser); } public static CurrentUser currentUser() { return CURRENT_USER.get(); } public static void remove() { CURRENT_USER.remove(); } }
package com.example.demo.test; import lombok.Getter; import lombok.Setter; import java.io.Serializable; import java.util.List; @Getter @Setter public class CurrentUser implements Serializable { private static final long serialVersionUID = -327159787234887122L; private Long id; private String jwtId; private String nickName; private String userName; private String phone; private Long deptId; private String deptName; private Integer level; private Integer flag; private ListauthorityList; }
package com.example.demo.test; import lombok.Getter; import lombok.Setter; @Getter @Setter public class JwtInfo implements java.io.Serializable { private String jwtId; private Long userId; private String token; }
package com.example.demo.test; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.UUID; import cn.hutool.jwt.JWT; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; public class JwtTool { private static int expDays = 7; private static String issuer = "xxxxxx"; private static String key = "xxxxx"; public interface Payload { String userId = "userId"; String jwtId = "jwtId"; } public static JwtInfo createJwtToken(Long userId) { String jwtId = UUID.randomUUID().toString(); try { String token = JWT.create() .setIssuer(issuer) .setIssuedAt(DateTime.now()) .setJWTId(jwtId) .setCharset(Charset.forName("utf-8")) //有效载荷 .setPayload(Payload.userId, userId) .setPayload(Payload.jwtId, jwtId) .setKey(key.getBytes("utf-8")) //7天有效期 .setExpiresAt(DateUtil.offsetDay(DateUtil.date(), expDays)) .sign(); JwtInfo jwtInfo = new JwtInfo(); jwtInfo.setUserId(userId); jwtInfo.setJwtId(jwtId); jwtInfo.setToken(token); return jwtInfo; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } public static String checkJwtToken(String token) { JWT jwt = JWT.of(token); //如果验证成功 boolean status; try { status = jwt.setKey(key.getBytes("utf-8")).verify(); if (status) { Object jwtId = jwt.getPayload(Payload.jwtId); if (jwtId != null) { return jwtId.toString(); } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } public static String getUserId(String token) { JWT jwt = JWT.of(token); return jwt.getPayload(Payload.userId).toString(); } }
package com.example.demo.test; public interface RedisKey { String TOKEN = "token:%s:%s"; static String getToken(String id, String jwtId) { String format = String.format(TOKEN, id,jwtId); return format; } }
package com.example.demo.test; public class ServiceException extends RuntimeException { private static final long serialVersionUID = 5909435651426033878L; private Integer code; public ServiceException(String message) { super(message); this.code = 201; } public ServiceException(Integer code, String message) { super(message); this.code = code; } public ServiceException(Throwable cause) { super(cause); } public ServiceException(String message, Throwable cause) { super(message, cause); } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } }
package com.example.demo.test; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Getter; import lombok.Setter; import java.io.Serializable; import java.util.Date; @Getter @Setter public class User implements Serializable { private Long id; private String name; @JsonIgnore private String password; private String userName; private Date createTime; }二、将拦截器加入系统拦截器
package com.example.demo.config; import com.example.demo.test.LoginInterceptor; 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 WebConfig implements WebMvcConfigurer { @Bean public LoginInterceptor loginInterceptor() { return new LoginInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor()) .addPathPatterns("/**") .excludePathPatterns( "/api/admin/common/user/login/**", "/api/admin/common/user/kaptcha/**" ); } }三、系统任何位置获取当前登录用户方式
CurrentUser currentUser = CurrentUserUtil.currentUser();
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)