跳到主要内容

ws token 鉴权、校验

介绍

有时,我们需要在 WebSocket 建立连接前做 Token 相关鉴权、校验的业务。 如果校验没通过,我们就不建立 ws 连接了,在 http 阶段就结束所有流程,可以有效的减少恶意长连接。

框架支持此类业务的扩展,我们可以在对外服部分做相关扩展。

使用场景

WebSocket Token 通常用于身份验证和授权访问 WebSocket 连接。 当客户端尝试建立 WebSocket 连接时,服务器可以要求客户端提供一个有效的令牌作为身份验证凭据。

使用 WebSocket Token 可以实现以下功能

  • 身份验证 :通过验证令牌,服务器可以确定客户端的身份,并决定是否允许其建立 WebSocket 连接。
  • 授权访问 :令牌可以用于授权访问特定资源或执行特定操作,服务器可以根据令牌的权限级别来限制客户端对 WebSocket 连接的访问权限。
  • 安全性 :通过使用令牌进行身份验证和授权,可以提高 WebSocket 连接的安全性。 持有有效令牌的客户端才能与服务器建立连接,并且只有获得授权的客户端才能执行相应的操作。

总而言之,WebSocket Token 是一种用于身份验证和授权访问 WebSocket 连接的机制,可以提供安全性和权限控制。

Example Source Code

see https://github.com/iohao/ionet-examples

path : ionet-cookbook-code

  • MyWebSocketVerifyHandler
  • WsVerifyApplication
  • WsClient

自定义 WebSocketVerifyHandler

现在,我们自定义一个验证类 MyWebSocketVerifyHandler,继承 WebSocketVerifyHandler 并重写 verify 方法。

  • code 5,通过 params 获取 key:value 格式的参数
  • code 11~18,创建一个请求并发送给逻辑服。
  • code 23,返回 true 表示验证通过,返回 false 框架会关闭当前连接
public final class MyWebSocketVerifyHandler extends WebSocketVerifyHandler {
@Override
protected boolean verify(SocketUserSession userSession, Map<String, String> params) {
// ws://127.0.0.1:10100/websocket?token=abc&name=aaaa
String token = params.get("token");
boolean verifyResult = "abc".equals(token);
log.info("verify name: {}", params.get("name"));

if (verifyResult) {
// Send a login message
var cmdInfo = HallCmd.of(HallCmd.loginVerify);
byte[] data = DataCodecManager.getDataCodec().encode(token);

var message = userSession.ofMessage(cmdInfo);
message.setData(data);

// send message to logicServer
this.convenientCommunication.request(message);
}

// 返回 true 表示验证通过,返回 false 框架会关闭连接。
// Return true means verification passed, return false means the framework will close the connection.
return verifyResult;
}
}
提示

userSession : 是当前连接的 UserSession。

params : 当连接为 ws://127.0.0.1:10100/websocket?token=abc&name=aaaa 时。 连接 “?” 之后的参数会存放在 map params 中,格式为 k-v,如:

  • token=abc
  • name=aaaa

如何使用

创建对外服,并重写 WebSocketMicroBootstrapFlow.createVerifyHandler 方法。

  • code 6,设置自定义的验证类。
ExternalServer createExternalServer() {
var builder = ExternalMapper.builder(ExternalGlobalConfig.externalPort);

// WebSocketVerifyHandler
var microBootstrapFlow = new WebSocketMicroBootstrapFlow();
microBootstrapFlow.verifyHandler = new MyWebSocketVerifyHandler();
builder.setMicroBootstrapFlow(microBootstrapFlow);

return builder.build();
}

在模拟客户端中测试

  • code 7,在模拟客户端中设置需要测试的 WebsocketVerify
public final class WsClient {
static void main() {
String websocketVerify = "?token=abc&name=aaaa";

new ClientRunOne()
...
.setWebsocketVerify(websocketVerify)
.startup();
}

...
}