I am trying to connect to my Javalin-Backend with a websocket in js. This is my Access-Manager in 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);
}
Now every websocket-connection also passes the acces manager from javalin by default. But my websocket connection failes due to missing header ("token").
Here is my code of the websocket-connection:
const socket = new WebSocket("wss://luxcars-api.lukas.bayern/chat", "your-subprotocol", {
headers: {
'token': getCookie('token')
}
});
Does anyone know, how to set the header direct at connection? In the Javalin documentation (https://javalin.io/documentation#wscontext) there is also the header method for WebSocketContext. But how to set the header?
I can't wait for the first message because my access manager prevents the connection.
Thanks a lot.
This will come as a cold shower, but browsers cannot send HTTP headers during a WebSocket handshake, despite it being a regular HTTP request, except for a few special headers outside of your control, and the WebSocket sub-protocol header
Sec-WebSocket-Protocol
, which is the only one you have control over. So it's not your Java code that's the issue.There are various workarounds you can try, including smuggling your token as a sub-protocol, since
Sec-WebSocket-Protocol
can have multiple values. See my (insanely comprehensive) answer here: https://stackoverflow.com/a/77060459/294657