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请求
    }

标签

发表评论