iohao / ioGame

无锁异步化、事件驱动架构设计的 java netty 网络编程框架; 轻量级,无需依赖任何第三方中间件或数据库就能支持集群、分布式; 适用于网络游戏服务器、物联网、内部系统及各种需要长连接的场景; 通过 ioGame 你可以很容易的搭建出一个集群无中心节点、集群自动化、分布式的网络服务器;FXGL、Unity、UE、Cocos Creator、Godot、Netty、Protobuf、webSocket、tcp、socket;java Netty 游戏服务器框架;
http://game.iohao.com
GNU Affero General Public License v3.0
904 stars 201 forks source link

关于外服中校验WebSocketVerifyHandler中如何排除指定url #360

Closed wallacefw1987 closed 2 months ago

wallacefw1987 commented 2 months ago

你的问题 | 使用场景

https://www.yuque.com/iohao/game/tb1126szmgfu6u55 有问题请教?这个demo中应该是对所有websocket进行校验,但是注册、登录应该排除token校验,可惜没有类似扩展工具获取到ws的url来判断哪些需要校验?哪些排除校验?

预期值

期望的预期值:我获取到url是ws:ip:port/register或者是ws:ip:port/login,我排除校验,返回true,其他需要校验后,得出结果

版本

iohao commented 2 months ago

子类可重写以下方法

重写 channelRead 方法,可以做自定义排除 https://github.com/iohao/ioGame/blob/e6188c4017a624c50f602ddcee38af73e36a5e4e/external/external-netty/src/main/java/com/iohao/game/external/core/netty/handler/ws/WebSocketVerifyHandler.java#L49-L72

重写 getParams 方法,可获取 uri https://github.com/iohao/ioGame/blob/e6188c4017a624c50f602ddcee38af73e36a5e4e/external/external-netty/src/main/java/com/iohao/game/external/core/netty/handler/ws/WebSocketVerifyHandler.java#L92-L98


最后,通常来说 ws token 鉴权、校验用在登录校验比较合适。

wallacefw1987 commented 2 months ago

ok,我试一试

wallacefw1987 commented 2 months ago

的issues的问题的延伸:上面重写WebSocketVerifyHandler中verify方法没问题!我现在的问题是这个比如在: WebSocketVerifyHandler的channelRead方法

在下面代码中:

 @Override 
 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 
     if (msg instanceof FullHttpRequest request) { 
         // 从 uri 中解析参数 
         String uri = request.uri(); 
         Map<String, String> params = getParams(uri); 

         // 开发者可以重写 verify 方法来扩展 
         SocketUserSession userSession = userSessions.getUserSession(ctx); 
         boolean verify = verify(userSession, params); 

         if (verify) { 
             //  验证通过后,移除自身;减少消息在 handler 中流动的次数 
             ctx.pipeline().remove(this); 
         } else { 
             // 验证失败,关闭连接或返回错误响应 
             FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.UNAUTHORIZED); 
             ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); 
             return; 
         } 
     } 

     super.channelRead(ctx, msg); 
 } 

又或者MyWebSocketVerifyHandler.java自己重写verify方法。哪里可以获取到客户端发来的信息,比如我要做校验的时候:我需要如下这两个数据,以demo为例子:

 public void initInputCommand() {
            // 模拟请求的主路由
            inputCommandCreate.cmd = LoginCmd.cmd;

            //整合结果没有问题
            ofCommand(LoginCmd.login).setTitle("登录").setRequestData(()->{
                XXXReq req = new XXXReq();
                req.setXXX("xxxx");
                req.setToken("eoclsdogj");
                return req;
            }).callback(result -> {
                MsgResp value = result.getValue(MsgResp.class);
                log.info("value : {}", value);
            });

我希望能够获取到InputCommand中cmd数据例如:LoginCmd.login以及 XXXReq 中的token 这个具体哪里可以获取到?

iohao commented 2 months ago

无法在建立连接前的验证中获取,因为 WebSocketVerifyHandler 的消息类型是 msg instanceof FullHttpRequest request;可通过 ws://127.0.0.1:10100/websocket?token=eoclsdogj&xxx=xxxx 传值。