我正在尝试使用 js 中的 websocket 连接到我的 Javalin 后端。 这是我的 Javalin 访问管理器:
@Override
public void manage(@NotNull Handler handler, @NotNull Context context, @NotNull Set<? extends RouteRole> set) throws Exception {
if (set.isEmpty()) {
handler.handle(context);
return;
}
String token = context.header("token");
if (token == null) {
context.status(HttpStatus.UNAUTHORIZED);
return;
}
Integer userId = this.tokenService.getUserIdByToken(token).orElse(null);
if (userId == null) {
context.status(HttpStatus.UNAUTHORIZED);
return;
}
Account account = this.accountService.getAccount(userId).orElse(null);
if (account == null || account.isDisabled()) {
context.status(HttpStatus.FORBIDDEN);
return;
}
if (set.contains(AuthenticationLevel.ADMIN) && !account.isAdministrator()) {
context.status(HttpStatus.FORBIDDEN);
return;
}
context.attribute(Constants.ACCOUNT_ATTRIBUTE_KEY, account);
handler.handle(context);
}
现在每个 websocket 连接也默认通过 javalin 的访问管理器。但我的 websocket 连接由于缺少标头(“令牌”)而失败。
这是我的 websocket 连接代码:
const socket = new WebSocket("wss://luxcars-api.lukas.bayern/chat", "your-subprotocol", {
headers: {
'token': getCookie('token')
}
});
有谁知道如何在连接时直接设置标头? 在 Javalin 文档 (https://javalin.io/documentation#wscontext) 中还有 WebSocketContext 的标头方法。但如何设置标题呢?
我等不及第一条消息,因为我的访问管理器阻止了连接。
非常感谢。
这就像一场冷水澡,但浏览器无法在 WebSocket 握手期间发送 HTTP 标头,尽管它是常规 HTTP 请求,除了一些不受您控制的特殊标头,以及 WebSocket 子协议标头
Sec-WebSocket-Protocol
是您唯一可以控制的。所以问题不是你的 Java 代码。
您可以尝试多种解决方法,包括将您的代币作为子协议走私。请参阅我的(非常全面)答案:https://stackoverflow.com/a/77060459/294657