1、websocket鉴权失败时响应ReplyBody,告知客户端鉴权失败

This commit is contained in:
远方夕阳 2022-05-10 17:07:39 +08:00
parent 7579845369
commit 461be0fab1
12 changed files with 193 additions and 65 deletions

View File

@ -13,7 +13,7 @@ import java.util.function.Predicate;
public class HandshakePredicate implements Predicate<HandshakeEvent> { public class HandshakePredicate implements Predicate<HandshakeEvent> {
/** /**
* * 验证身份信息本方法切勿进行耗时操作
* @param event * @param event
* @return true验证通过 false验证失败 * @return true验证通过 false验证失败
*/ */

View File

@ -29,18 +29,25 @@
function onReplyReceived(reply) function onReplyReceived(reply)
{ {
console.log(reply); console.log(reply);
if(reply.key==='client_bind' && reply.code === "200" ) if (reply.key === KEY_CLIENT_BIND && reply.code === CODE_OK) {
{
hideProcess(); hideProcess();
$('#LoginDialog').fadeOut(); $('#LoginDialog').fadeOut();
$('#MessageDialog').fadeIn(); $('#MessageDialog').fadeIn();
$('#MessageDialog').addClass("in"); $('#MessageDialog').addClass("in");
$("#current_account").text($('#account').val()); $("#current_account").text($('#account').val());
} }
/**
* 链接鉴权失败
*/
if(reply.key === KEY_HANDSHAKE && reply.code === CODE_UNAUTHORIZED){
hideProcess();
showETip("鉴权失败");
}
} }
/** 当收到消息时候回调 **/ /** 当收到消息时候回调 **/

View File

@ -21,6 +21,16 @@ const REPLY_BODY = 4;
const SENT_BODY = 3; const SENT_BODY = 3;
const PING = 1; const PING = 1;
const PONG = 0; const PONG = 0;
/*
* 握手鉴权常量
*/
const KEY_HANDSHAKE = "client_handshake";
const CODE_UNAUTHORIZED = "401";
const CODE_OK = "200";
const KEY_CLIENT_BIND = "client_bind";
/** /**
* PONG字符串转换后 * PONG字符串转换后
* @type {Uint8Array} * @type {Uint8Array}
@ -54,7 +64,7 @@ CIMPushManager.bind = function (account) {
let browser = getBrowser(); let browser = getBrowser();
let body = new proto.com.farsunset.cim.sdk.web.model.SentBody(); let body = new proto.com.farsunset.cim.sdk.web.model.SentBody();
body.setKey("client_bind"); body.setKey(KEY_CLIENT_BIND);
body.setTimestamp(new Date().getTime()); body.setTimestamp(new Date().getTime());
body.getDataMap().set("uid", account); body.getDataMap().set("uid", account);
body.getDataMap().set("channel", APP_CHANNEL); body.getDataMap().set("channel", APP_CHANNEL);
@ -106,7 +116,8 @@ CIMPushManager.innerOnMessageReceived = function (e) {
if (type === REPLY_BODY) { if (type === REPLY_BODY) {
let message = proto.com.farsunset.cim.sdk.web.model.ReplyBody.deserializeBinary(body); let message = proto.com.farsunset.cim.sdk.web.model.ReplyBody.deserializeBinary(body);
/**
/*
* 将proto对象转换成json对象去除无用信息 * 将proto对象转换成json对象去除无用信息
*/ */
let reply = {}; let reply = {};
@ -116,13 +127,21 @@ CIMPushManager.innerOnMessageReceived = function (e) {
reply.timestamp = message.getTimestamp(); reply.timestamp = message.getTimestamp();
reply.data = {}; reply.data = {};
/** /*
* 注意遍历map这里的参数 value在前key在后 * 注意遍历map这里的参数 value在前key在后
*/ */
message.getDataMap().forEach(function (v, k) { message.getDataMap().forEach(function (v, k) {
reply.data[k] = v; reply.data[k] = v;
}); });
/*
* 判断是否是握手鉴权失败
* 终止后续自动重连
*/
if(reply.key === KEY_HANDSHAKE && reply.code === CODE_UNAUTHORIZED){
manualStop = true;
}
onReplyReceived(reply); onReplyReceived(reply);
} }
}; };

View File

@ -1,5 +1,5 @@
/*CIM服务器IP*/ /*CIM服务器IP*/
const CIM_HOST = "127.0.0.1"; const CIM_HOST = window.location.hostname;
/* /*
*服务端 websocket端口 *服务端 websocket端口
*/ */
@ -7,7 +7,7 @@ const CIM_PORT = 34567;
const CIM_URI = "ws://" + CIM_HOST + ":" + CIM_PORT; const CIM_URI = "ws://" + CIM_HOST + ":" + CIM_PORT;
const APP_VERSION = "1.0.0"; const APP_VERSION = "1.0.0";
const APP_CHANNEL = "browser"; const APP_CHANNEL = "web";
const APP_PACKAGE = "com.farsunset.cim"; const APP_PACKAGE = "com.farsunset.cim";
/* /*
@ -18,6 +18,25 @@ const DATA_HEADER_LENGTH = 1;
const MESSAGE = 2; const MESSAGE = 2;
const REPLY_BODY = 4; const REPLY_BODY = 4;
const SENT_BODY = 3;
const PING = 1;
const PONG = 0;
/*
* 握手鉴权常量
*/
const KEY_HANDSHAKE = "client_handshake";
const CODE_UNAUTHORIZED = "401";
const CODE_OK = "200";
const KEY_CLIENT_BIND = "client_bind";
/**
* PONG字符串转换后
* @type {Uint8Array}
*/
const PONG_BODY = new Uint8Array([80,79,78,71]);
let socket; let socket;
let manualStop = false; let manualStop = false;
@ -33,27 +52,28 @@ CIMPushManager.connect = function () {
socket.onclose = CIMPushManager.innerOnConnectionClosed; socket.onclose = CIMPushManager.innerOnConnectionClosed;
}; };
CIMPushManager.bindAccount = function (account) { CIMPushManager.bind = function (account) {
window.localStorage.account = account; window.localStorage.account = account;
let deviceId = window.localStorage.deviceIddeviceId; let deviceId = window.localStorage.deviceId;
if (deviceId == '' || deviceId == undefined) { if (deviceId === '' || deviceId === undefined) {
deviceId = generateUUID(); deviceId = generateUUID();
window.localStorage.deviceId = deviceId; window.localStorage.deviceId = deviceId;
} }
let browser = getBrowser(); let browser = getBrowser();
let body = new proto.com.farsunset.cim.sdk.web.model.SentBody(); let body = new proto.com.farsunset.cim.sdk.web.model.SentBody();
body.setKey("client_bind"); body.setKey(KEY_CLIENT_BIND);
body.setTimestamp(new Date().getTime()); body.setTimestamp(new Date().getTime());
body.getDataMap().set("account", account); body.getDataMap().set("uid", account);
body.getDataMap().set("channel", APP_CHANNEL); body.getDataMap().set("channel", APP_CHANNEL);
body.getDataMap().set("appVersion", APP_VERSION); body.getDataMap().set("appVersion", APP_VERSION);
body.getDataMap().set("osVersion", browser.version); body.getDataMap().set("osVersion", browser.version);
body.getDataMap().set("packageName", APP_PACKAGE); body.getDataMap().set("packageName", APP_PACKAGE);
body.getDataMap().set("deviceId", deviceId); body.getDataMap().set("deviceId", deviceId);
body.getDataMap().set("device", browser.name); body.getDataMap().set("deviceName", browser.name);
body.getDataMap().set("language", navigator.language);
CIMPushManager.sendRequest(body); CIMPushManager.sendRequest(body);
}; };
@ -83,15 +103,21 @@ CIMPushManager.innerOnMessageReceived = function (e) {
let type = data[0]; let type = data[0];
let body = data.subarray(DATA_HEADER_LENGTH, data.length); let body = data.subarray(DATA_HEADER_LENGTH, data.length);
if (type == MESSAGE) { if (type === PING) {
CIMPushManager.pong();
return;
}
if (type === MESSAGE) {
let message = proto.com.farsunset.cim.sdk.web.model.Message.deserializeBinary(body); let message = proto.com.farsunset.cim.sdk.web.model.Message.deserializeBinary(body);
onInterceptMessageReceived(message.toObject(false)); onInterceptMessageReceived(message.toObject(false));
return; return;
} }
if (type == REPLY_BODY) { if (type === REPLY_BODY) {
let message = proto.com.farsunset.cim.sdk.web.model.ReplyBody.deserializeBinary(body); let message = proto.com.farsunset.cim.sdk.web.model.ReplyBody.deserializeBinary(body);
/**
/*
* 将proto对象转换成json对象去除无用信息 * 将proto对象转换成json对象去除无用信息
*/ */
let reply = {}; let reply = {};
@ -101,13 +127,21 @@ CIMPushManager.innerOnMessageReceived = function (e) {
reply.timestamp = message.getTimestamp(); reply.timestamp = message.getTimestamp();
reply.data = {}; reply.data = {};
/** /*
* 注意遍历map这里的参数 value在前key在后 * 注意遍历map这里的参数 value在前key在后
*/ */
message.getDataMap().forEach(function (v, k) { message.getDataMap().forEach(function (v, k) {
reply.data[k] = v; reply.data[k] = v;
}); });
/*
* 判断是否是握手鉴权失败
* 终止后续自动重连
*/
if(reply.key === KEY_HANDSHAKE && reply.code === CODE_UNAUTHORIZED){
manualStop = true;
}
onReplyReceived(reply); onReplyReceived(reply);
} }
}; };
@ -123,16 +157,24 @@ CIMPushManager.innerOnConnectionClosed = function (e) {
CIMPushManager.sendRequest = function (body) { CIMPushManager.sendRequest = function (body) {
let data = body.serializeBinary(); let data = body.serializeBinary();
let protobuf = new Uint8Array(data.length); let protobuf = new Uint8Array(data.length + 1);
protobuf.set(data, 0); protobuf[0] = SENT_BODY;
protobuf.set(data, 1);
socket.send(protobuf); socket.send(protobuf);
}; };
CIMPushManager.pong = function () {
let pong = new Uint8Array(PONG_BODY.byteLength + 1);
pong[0] = PONG;
pong.set(PONG_BODY,1);
socket.send(pong);
};
function onInterceptMessageReceived(message) { function onInterceptMessageReceived(message) {
/* /*
*被强制下线之后不再继续连接服务端 *被强制下线之后不再继续连接服务端
*/ */
if (message.action == ACTION_999) { if (message.action === ACTION_999) {
manualStop = true; manualStop = true;
} }
/* /*
@ -174,7 +216,7 @@ function generateUUID() {
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = (d + Math.random() * 16) % 16 | 0; let r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16); d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
}); });
return uuid.replace(/-/g, ''); return uuid.replace(/-/g, '');
} }

View File

@ -33,4 +33,6 @@ public interface CIMConstant {
String CLIENT_CONNECT_CLOSED = "client_closed"; String CLIENT_CONNECT_CLOSED = "client_closed";
String CLIENT_HANDSHAKE = "client_handshake";
} }

View File

@ -21,12 +21,13 @@
*/ */
package com.farsunset.cim.handshake; package com.farsunset.cim.handshake;
import com.farsunset.cim.constant.CIMConstant;
import com.farsunset.cim.model.ReplyBody;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -36,12 +37,12 @@ import java.util.function.Predicate;
*/ */
@ChannelHandler.Sharable @ChannelHandler.Sharable
public class HandshakeHandler extends ChannelInboundHandlerAdapter { public class HandshakeHandler extends ChannelInboundHandlerAdapter {
/* /*
客户端接收到的CloseEvent事件类型 *认证失败返回replyBody给客户端
客户端可通过该code判断是握手鉴权失败
*/ */
private static final int UNAUTHORIZED_CODE = 4001; private final ReplyBody failedBody = ReplyBody.make(CIMConstant.CLIENT_HANDSHAKE,
HttpResponseStatus.UNAUTHORIZED.code(),
HttpResponseStatus.UNAUTHORIZED.reasonPhrase());
private final Predicate<HandshakeEvent> handshakePredicate; private final Predicate<HandshakeEvent> handshakePredicate;
@ -67,10 +68,10 @@ public class HandshakeHandler extends ChannelInboundHandlerAdapter {
} }
/* /*
* 鉴权不通过关闭链接 * 鉴权不通过发送响应体并关闭链接
*/ */
if (!handshakePredicate.test(HandshakeEvent.of(event))) { if (!handshakePredicate.test(HandshakeEvent.of(event))) {
context.channel().writeAndFlush(new CloseWebSocketFrame(UNAUTHORIZED_CODE,HttpResponseStatus.UNAUTHORIZED.reasonPhrase())).addListener(ChannelFutureListener.CLOSE); context.channel().writeAndFlush(failedBody).addListener(ChannelFutureListener.CLOSE);
} }
} }
} }

View File

@ -148,4 +148,12 @@ public class ReplyBody implements Serializable, Transportable {
public DataType getType() { public DataType getType() {
return DataType.REPLY; return DataType.REPLY;
} }
public static ReplyBody make(String key,int code,String message){
ReplyBody body = new ReplyBody();
body.key = key;
body.code = String.valueOf(code);
body.message = message;
return body;
}
} }

View File

@ -26,18 +26,24 @@
function onReplyReceived(reply) function onReplyReceived(reply)
{ {
console.log(reply); console.log(reply);
if(reply.key==='client_bind' && reply.code === "200" ) if (reply.key === KEY_CLIENT_BIND && reply.code === CODE_OK) {
{
hideProcess(); hideProcess();
$('#LoginDialog').fadeOut(); $('#LoginDialog').fadeOut();
$('#MessageDialog').fadeIn(); $('#MessageDialog').fadeIn();
$('#MessageDialog').addClass("in"); $('#MessageDialog').addClass("in");
$("#current_account").text($('#account').val()); $("#current_account").text($('#account').val());
} }
/**
* 链接鉴权失败
*/
if(reply.key === KEY_HANDSHAKE && reply.code === CODE_UNAUTHORIZED){
hideProcess();
showETip("鉴权失败");
}
} }
/** 当收到消息时候回调 **/ /** 当收到消息时候回调 **/

View File

@ -21,6 +21,16 @@ const REPLY_BODY = 4;
const SENT_BODY = 3; const SENT_BODY = 3;
const PING = 1; const PING = 1;
const PONG = 0; const PONG = 0;
/*
* 握手鉴权常量
*/
const KEY_HANDSHAKE = "client_handshake";
const CODE_UNAUTHORIZED = "401";
const CODE_OK = "200";
const KEY_CLIENT_BIND = "client_bind";
/** /**
* PONG字符串转换后 * PONG字符串转换后
* @type {Uint8Array} * @type {Uint8Array}
@ -53,7 +63,7 @@ CIMPushManager.bind = function (account) {
let browser = getBrowser().name; let browser = getBrowser().name;
let body = {}; let body = {};
body.key ="client_bind"; body.key = KEY_CLIENT_BIND;
body.timestamp=new Date().getTime(); body.timestamp=new Date().getTime();
body.data = {}; body.data = {};
body.data.uid = account; body.data.uid = account;
@ -107,6 +117,13 @@ CIMPushManager.innerOnMessageReceived = function (e) {
if (type === REPLY_BODY) { if (type === REPLY_BODY) {
let reply = JSON.parse(body); let reply = JSON.parse(body);
/*
* 判断是否是握手鉴权失败
* 终止后续自动重连
*/
if(reply.key === KEY_HANDSHAKE && reply.code === CODE_UNAUTHORIZED){
manualStop = true;
}
onReplyReceived(reply); onReplyReceived(reply);
} }
}; };

View File

@ -29,18 +29,24 @@
function onReplyReceived(reply) function onReplyReceived(reply)
{ {
console.log(reply); console.log(reply);
if(reply.key==='client_bind' && reply.code === "200" ) if (reply.key === KEY_CLIENT_BIND && reply.code === CODE_OK) {
{
hideProcess(); hideProcess();
$('#LoginDialog').fadeOut(); $('#LoginDialog').fadeOut();
$('#MessageDialog').fadeIn(); $('#MessageDialog').fadeIn();
$('#MessageDialog').addClass("in"); $('#MessageDialog').addClass("in");
$("#current_account").text($('#account').val()); $("#current_account").text($('#account').val());
} }
/**
* 链接鉴权失败
*/
if(reply.key === KEY_HANDSHAKE && reply.code === CODE_UNAUTHORIZED){
hideProcess();
showETip("鉴权失败");
}
} }
/** 当收到消息时候回调 **/ /** 当收到消息时候回调 **/

View File

@ -21,6 +21,16 @@ const REPLY_BODY = 4;
const SENT_BODY = 3; const SENT_BODY = 3;
const PING = 1; const PING = 1;
const PONG = 0; const PONG = 0;
/*
* 握手鉴权常量
*/
const KEY_HANDSHAKE = "client_handshake";
const CODE_UNAUTHORIZED = "401";
const CODE_OK = "200";
const KEY_CLIENT_BIND = "client_bind";
/** /**
* PONG字符串转换后 * PONG字符串转换后
* @type {Uint8Array} * @type {Uint8Array}
@ -54,7 +64,7 @@ CIMPushManager.bind = function (account) {
let browser = getBrowser(); let browser = getBrowser();
let body = new proto.com.farsunset.cim.sdk.web.model.SentBody(); let body = new proto.com.farsunset.cim.sdk.web.model.SentBody();
body.setKey("client_bind"); body.setKey(KEY_CLIENT_BIND);
body.setTimestamp(new Date().getTime()); body.setTimestamp(new Date().getTime());
body.getDataMap().set("uid", account); body.getDataMap().set("uid", account);
body.getDataMap().set("channel", APP_CHANNEL); body.getDataMap().set("channel", APP_CHANNEL);
@ -63,6 +73,7 @@ CIMPushManager.bind = function (account) {
body.getDataMap().set("packageName", APP_PACKAGE); body.getDataMap().set("packageName", APP_PACKAGE);
body.getDataMap().set("deviceId", deviceId); body.getDataMap().set("deviceId", deviceId);
body.getDataMap().set("deviceName", browser.name); body.getDataMap().set("deviceName", browser.name);
body.getDataMap().set("language", navigator.language);
CIMPushManager.sendRequest(body); CIMPushManager.sendRequest(body);
}; };
@ -105,7 +116,8 @@ CIMPushManager.innerOnMessageReceived = function (e) {
if (type === REPLY_BODY) { if (type === REPLY_BODY) {
let message = proto.com.farsunset.cim.sdk.web.model.ReplyBody.deserializeBinary(body); let message = proto.com.farsunset.cim.sdk.web.model.ReplyBody.deserializeBinary(body);
/**
/*
* 将proto对象转换成json对象去除无用信息 * 将proto对象转换成json对象去除无用信息
*/ */
let reply = {}; let reply = {};
@ -115,13 +127,21 @@ CIMPushManager.innerOnMessageReceived = function (e) {
reply.timestamp = message.getTimestamp(); reply.timestamp = message.getTimestamp();
reply.data = {}; reply.data = {};
/** /*
* 注意遍历map这里的参数 value在前key在后 * 注意遍历map这里的参数 value在前key在后
*/ */
message.getDataMap().forEach(function (v, k) { message.getDataMap().forEach(function (v, k) {
reply.data[k] = v; reply.data[k] = v;
}); });
/*
* 判断是否是握手鉴权失败
* 终止后续自动重连
*/
if(reply.key === KEY_HANDSHAKE && reply.code === CODE_UNAUTHORIZED){
manualStop = true;
}
onReplyReceived(reply); onReplyReceived(reply);
} }
}; };