一、依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.32</version>
</dependency>
</dependencies>
二、工具类
package com.example.demo.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.example.demo.contant.RequestKeyConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class JWTUtils {
// token 签名的秘钥,可设置到配置文件中
private static final String SECRET_KEY = "secretKey:123456";
// token过期时间
public static final long TOKEN_EXPIRE_TIME = 7200 * 1000;
/**
* 生成jwt
*/
public static String createJwt(String userId) {
Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
//设置头信息
HashMap<String, Object> header = new HashMap<>(2);
header.put("typ", "JWT");
header.put("alg", "HS256");
// 生成 token:头部+载荷+签名
return JWT.create().withHeader(header)
.withClaim(RequestKeyConstants.USER_ID, userId)
.withExpiresAt(new Date(System.currentTimeMillis() + TOKEN_EXPIRE_TIME)).sign(algorithm);
}
public static Map<String, Claim> parseJwt(String token) {
Map<String, Claim> claims = null;
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
claims = jwt.getClaims();
return claims;
} catch (Exception e) {
log.error("jwt token {} 解析异常",token);
return null;
}
}
/**
* 解析jwt
*/
public static Long getUserId(String token) {
try {
Map<String, Claim> claims = parseJwt(token);
if (claims != null) {
String userId = claims.get(RequestKeyConstants.USER_ID).asString();
if (StringUtils.hasLength(userId)) {
return Long.valueOf(userId);
}
}
} catch (Exception e) {
log.error("jwt token {} 解析异常",token);
}
return null;
}
}
三、拦截器
package com.example.demo.intercept; import com.alibaba.fastjson.JSONObject; import com.auth0.jwt.interfaces.Claim; import com.example.demo.contant.RequestKeyConstants; import com.example.demo.util.JWTUtils; import com.example.demo.util.RequestContext; import com.example.demo.util.UserLoginContextHolder; import lombok.extern.slf4j.Slf4j; import org.apache.logging.log4j.ThreadContext; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; @Slf4j public class RequestProcessInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("token"); if(!StringUtils.hasLength(token)) { token = request.getParameter("token"); } if(!StringUtils.hasLength(token)){ Map<String,Object> map = new HashMap<>(); map.put("err",100); map.put("msg","请先登录"); String json = JSONObject.toJSONString(map); //设置响应头(告知浏览器:响应的数据类型为json、响应的数据编码表为utf-8) response.setContentType("application/json;charset=utf-8"); //响应 response.getWriter().write(json); return false;//不放行 } //5.解析token,如果解析失败,返回错误结果(未登录) try { Long userId = JWTUtils.getUserId(token);//获取用户的基本信息 RequestContext context = UserLoginContextHolder.get() == null ? new RequestContext() : UserLoginContextHolder.get(); this.setCookies(request, context); context.setUserId(Long.valueOf(userId)); UserLoginContextHolder.set(context); }catch (Exception e){ Map<String,Object> map = new HashMap<>(); map.put("err",101); map.put("msg","token不正确"); String json = JSONObject.toJSONString(map); //设置响应头 response.setContentType("application/json;charset=utf-8"); //响应 response.getWriter().write(json); return false; } //6.放行 return true; } public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { UserLoginContextHolder.remove(); ThreadContext.clearAll(); } private void setCookies(HttpServletRequest request, RequestContext requestContext) { Cookie[] cookies = request.getCookies(); requestContext.setCookies(cookies); } }
package com.example.demo.contant; public class RequestKeyConstants { public static final String USER_ID="curr_user_id"; }
·当前用户信息承载类
package com.example.demo.util; import lombok.Data; import javax.servlet.http.Cookie; @Data public class RequestContext { private Long userId; //当前用户ID private String deviceId; //设备id private String deviceType; //设备类型 private String appVersion; //APP版本 private String ip;//客户端IP private String requestId; private Cookie[] cookies; }
package com.example.demo.util; public class UserLoginContextHolder { private static final InheritableThreadLocal<RequestContext> REQUEST_CONTEXT_INHERITABLE_THREAD_LOCAL = new InheritableThreadLocal(); public UserLoginContextHolder() { } public static RequestContext get() { return (RequestContext)REQUEST_CONTEXT_INHERITABLE_THREAD_LOCAL.get(); } public static void set(RequestContext context) { REQUEST_CONTEXT_INHERITABLE_THREAD_LOCAL.set(context); } public static void remove() { REQUEST_CONTEXT_INHERITABLE_THREAD_LOCAL.remove(); } }
package com.example.demo.config; import com.example.demo.intercept.RequestProcessInterceptor; 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 WebAppConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new RequestProcessInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/login", "/register", "/image/**", "/js/**", "/css/**") .order(0); } }
package com.example.demo.controller; import com.example.demo.util.JWTUtils; import com.example.demo.util.RequestContext; import com.example.demo.util.UserLoginContextHolder; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.Cookie; @RestController @Slf4j public class LoginController { @RequestMapping("/login") public String create(@RequestParam("userId") Long userId) { String token = JWTUtils.createJwt(userId + ""); return token; } @RequestMapping("/auth/parse") public RequestContext parse() { RequestContext requestContext = UserLoginContextHolder.get(); Cookie[] cookies = requestContext.getCookies(); StringBuilder sb = new StringBuilder(); for (Cookie cookie : cookies) { sb.append(cookie.getName()); sb.append("===="); sb.append(cookie.getValue()); sb.append("\r\n"); } log.info(sb.toString()); return requestContext; } }
浙公网安备 33010602011771号