Gateway转发Websocket并校验Token
内容目录
Gateway网关是支持ws://协议的
我们的websocket地址是@ServerEndpoint("/ws/imserver/{user}")
,但是前端登录后拿到的是token,所以前端带着token去请求,new WebSocket("ws://192.168.0.70:8801/ws/imserver?token="+token)
,在gateway校验token后,修改请求地址,改成websocket的地址。
1.配置转发规则
一般的http转发规则是lb://social-service
,websocket的转发规则就是lb:ws://social-service
,多了个ws。
- id: ws_im_route
uri: lb:ws://social-service
predicates:
- Path=/ws/imserver/**
- Header=Upgrade
token校验处理
token校验通过后,获取到登录用户ID,修改请求路径。
@Component
@Slf4j
public class AccessFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
// 处理websocket token start
URI requestUrl = exchange.getRequest().getURI();
if(requestUrl.getPath().contains("/ws/imserver")){
List<String> token = request.getQueryParams().get("token");
if(token != null && token.size() >0){
String userid = getUserIdByToken(token.get(0));
if(StringUtils.isNotBlank(userid)){
// token校验通过后,修改请求路径
String newPath =request.getPath()+"/"+userid;
ServerHttpRequest newRequest = request.mutate().path(newPath).build();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
return chain.filter(exchange.mutate().request(newRequest).build());
}
}
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "application/json; charset=utf-8");
String message = "{\"status\":99,\"message\":\"请登录后尝试\"}";
DataBuffer buffer = response.bufferFactory().wrap(message.getBytes());
return response.writeWith(Mono.just(buffer));
}
// 处理websocket token stop
// 处理其余的HTTP请求
}
发表评论