Netty的webSocket服务端的安全性的一些限制

548 阅读2分钟

「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战

服务端要求,欢迎给我留言和讨论

服务端会暴露在公网中,因此链接的安全性需要考虑。
防止数据篡改,和垃圾数据

这里以笔者写的简单web聊天系统为基础

走wss路线

mkcert测试证书生成

mkcert -p12-file keystore.p12 -pkcs12 192.168.0.103 127.0.0.1 localhost
默认配置`alias=1``password=changeit`

wss配置

//这里面的配置接受内容的长度过长,是因为当时做了写音视频编码为base64的转发
@Override
    public void initChannel(SocketChannel ch) throws Exception {
		ChannelPipeline pipeline = ch.pipeline();
		pipeline.addLast(new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS));
		pipeline.addLast(new HttpServerCodec());
		pipeline.addLast(new HttpObjectAggregator(1024 * 1024));
		pipeline.addLast(new ChunkedWriteHandler());
		pipeline.addLast(new WebSocketServerProtocolHandler("/ws", null, true, 1024 * 512));
		pipeline.addLast(new TextWebSocketFrameHandler());
		// 配置ssl访问的
		SSLContext sslContext = SslUtil.createSSLContext("PKCS12",
		this.getClass().getClassLoader().getResourceAsStream("keystore.p12"), "changeit"); // 
                SSLEngine engine =sslContext.createSSLEngine();
		SSLEngine sslEngine = sslContext.createSSLEngine();
		sslEngine.setNeedClientAuth(false);
		sslEngine.setUseClientMode(false);
		pipeline.addFirst(new SslHandler(sslEngine));
    }

新用户绑定验证

绑定的时候需要验证一下
这里用redis做了个缓存并加个过期时间:用户编码:token
这里登陆的是从其他服务登陆的,登录后会给创建个token缓存在redis用来共享

老用户验证

服务端保存的有长连接通道:用户名:链接通道
private static Map<ChartUser, Channel> userChannel = new ConcurrentHashMap <ChartUser, Channel>();

可以查看服务端链接的通道是否属于这个用户的,不然拒绝

断线重连

链接断开服务端会有个监听事件,移除链接
@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception { 
		Channel incoming = ctx.channel();
		logger.info("Client:" + incoming.remoteAddress() + "掉线");
		ChannelManager.removeChannelByChannel(incoming);
	}


前端这里以websocketd为例会触发ws.onclose方法
比如当前链接的服务端挂掉了,或者网络原因这里会触发这个方法
在这个方法里面我们依旧是从业务端1.获取tokenn
                              2.获取server的地址(ip+端口) 这里需要服务端做集群保证服务不断
                              3.重新绑定websocket服务端完成重连
                              4.失败可以添加重试次数