Skip to main content

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;
}
}
tip

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();
}

...
}