Netty websocket服务在url上携带参数
内容纲要
需求
- 在连接websocket时,对连接进行权限校验的方式一般为将身份信息放在url上或者连接上websocket后立马发送校验信息
- 放在url上的方式在连接的第一时刻就可以对该连接进行身份校验,可以避免连接浪费和编码复杂度,Tomcat-websocket对该方式有良好的支持,但是Netty在并没有对该方式进行支持,需要自己编码实现
- 连接后第一时间发送身份信息,该方式可以做到身份校验,但是链接之后需要定时检查用户是否授权,未授权则关闭通道,在此期间则会占用一个链接通道,降低服务器的连接数量
Netty中不支持的原因
- Netty实现WebSocket只需要在pipeline中添加一个WebSocketServerPortocolHandler就可以实现ws接口的暴露,因为安全问题,ws并不推荐通过queryString携带信息,所以Netty中WebSocketServerPortocolHandler模式的构造器要求连接建立是传入的URL与程序指定的路径完全匹配,所以该类中的checkStartsWith(校验url中前缀与指定的url相同即可)默认为false
Netty中pipeline的运行顺序
- 在Netty中,pipeline运行顺序为 header->入站处理器->tail->出站处理器->header
解决方案
- 我们可以在添加WebSocketServerPortocolHandler之前添加我们的InboundHandler并重写channelRead方法,并判断msg是否为FullHttpRequest(代表一个新的连接接入),获取到路由信息后,再将请求重定向回WebSocketServerPortocolHandler制定的路径即可
- 演示url: ws://local:port/path/{token} {token}为携带的路径参数
# 拦截器重新方法 @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //用户信息校验 if (msg instanceof FullHttpRequest) { FullHttpRequest request = (FullHttpRequest) msg; String uri = request.uri(); String token = uri.split("/")[2]; System.out.println(token); #重定向到/path request.setUri("/path"); super.channelRead(ctx, request); } else { super.channelRead(ctx, msg); } }
InboundHandler一定要在添加WebSocketServerPortocolHandler之前添加到pipeline中
共有 0 条评论