一、思路
1、登录成功时,使用userId生成token,让前端保存;
2、在后续请求进入网关时,创建一个过滤器,从token中解析出userId,并存入请求头中;
3、在请求到达目标服务时,创建一个拦截器,从请求头中取出userId,并获取用户PO,最后存入ThreadLocal<UserPO>中。
二、例子
1、在网关中创建过滤器,进行token鉴权,并取出userId存入请求头
import com.xzh.gateway.util.AppJwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class AuthorizeFilter implements Ordered, GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
if (request.getURI().getPath().contains("/login")) {
return chain.filter(exchange);
}
String token = request.getHeaders().getFirst("token");
if (StringUtils.isBlank(token)) {
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
try {
Claims claimsBody = AppJwtUtil.getClaimsBody(token);
int result = AppJwtUtil.verifyToken(claimsBody);
if (result == 1 || result == 2) {
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
Object userId = claimsBody.get("id");
ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> {
httpHeaders.add("userId", "" + userId);
}).build();
exchange.mutate().request(serverHttpRequest);
} catch (Exception e) {
e.printStackTrace();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
三、在服务中创建拦截器,从请求头中取出userId,获取UserPO,并存入ThreadLocal<UserPO>
import com.xzh.model.wemedia.pojos.WmUser;
import com.xzh.utils.thread.WmThreadLocalUtil;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class WmTokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String userId = request.getHeader("userId");
if (userId != null) {
WmUser wmUser = new WmUser();
wmUser.setId(Integer.valueOf(userId));
WmThreadLocalUtil.setWmUser(wmUser);
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
WmThreadLocalUtil.clear();
}
}
四、创建ThreadLocalUtil,供后续程序获取用户信息
import com.xzh.model.wemedia.pojos.WmUser;
public class WmThreadLocalUtil {
private static final ThreadLocal<WmUser> WM_USER_THREAD_LOCAL = new ThreadLocal<>();
public static WmUser getWmUser() {
return WM_USER_THREAD_LOCAL.get();
}
public static void setWmUser(WmUser wmUser) {
WM_USER_THREAD_LOCAL.set(wmUser);
}
public static void clear() {
WM_USER_THREAD_LOCAL.remove();
}
}