1
增加一个AuthHandler,顶在pipeline最前面
鉴权不通过,close channel,通过,remove掉这个鉴权channel
1.5
no remove AuthHandler
channel.attribute.get
null - 是否鉴权请求
否 close
是 鉴权
not null 直接放行ctx.fireChannelRead
2
connect时鉴权,将信息放在ws url中
前端:ws = new WebSocket(WS_URL + ";" + getCookie('token'));
服务端在握手前:
public class HttpRequestHandler extends SimpleChannelInboundHandler{ private static final Logger logger = LoggerFactory.getLogger(HttpRequestHandler.class); public static AttributeKey TOKEN = AttributeKey.valueOf("token"); public static AttributeKey USERNAME = AttributeKey.valueOf("userName"); @Override public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception { String url = request.getUri(); if(-1 != url.indexOf("/ws")) { String temp [] = url.split(";"); if(temp.length >= 2) { String token = URLDecoder.decode(temp[1], "UTF-8"); ctx.channel().attr(TOKEN).set(token); } request.setUri("/ws"); // 传递到下一个handler:升级握手 ctx.fireChannelRead(request.retain()); } else { logger.error("not socket"); ctx.close(); } }
握手后:
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) { // 移除性能更加 ctx.pipeline().remove(HttpRequestHandler.class); boolean hasAuth = false; String userName = null; String token = ctx.channel().attr(HttpRequestHandler.TOKEN).get(); if(token == null || "".equals(token)) { logger.warn("no token"); } else { userName = GlobalContext.channelUser.get(token); if(userName != null && !"".equals(userName)) { ctx.channel().attr(HttpRequestHandler.USERNAME).set(userName); hasAuth = true; } else { logger.warn("no user"); } } if(hasAuth) { String up = userName + "[connected]"; logger.info(up); // for(int i=0; i<100; ++i) ctx.writeAndFlush(up); group.add(ctx.channel()); } else { String noToken = "[您的token非法,请重新登录]"; logger.warn(noToken); ctx.writeAndFlush(noToken).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture channelFuture) throws Exception { channelFuture.channel().close(); } }); }
具体位置参见:https://www.cnblogs.com/silyvin/articles/9590595.html