1
增加一个AuthHandler,顶在pipeline最前面
鉴权不通过,close channel,通过,remove掉这个鉴权channelhandler
取自jds-im,msgforwarder AuthWsHandler
------------------------------------------------------------------------------------------------
* ctx.pipeline().remove(this);
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