1

I'm following Vert.x 4's SockJS documentation and noticed that each SockJSSocket inside my handler has a .webSession() and a .webUser(). However, both these fields are empty aside from the .webSession().id()

I have an AuthHandler registered on the sub-router that this socket handler is on, but the SockJS Client in my frontend is not capable of sending credentials in the HTTP upgrade request.

How am I supposed to populate these fields for use?

foxtrotuniform6969
  • 3,527
  • 7
  • 28
  • 54
  • I think you need to add the SessionHandler: `router.route().handler(SessionHandler.create(store)` – injecteer Jan 12 '21 at 12:15
  • As per the [docs](https://vertx.io/docs/vertx-web/java/#_requiring_authorization_for_messages) I had already added `SessionHandler.create(LocalSessionStore.create(vertx))` further up in my router to handle authentication. It works fine for HTTP requests because I add the JWT bearer, but I cannot figure out how to add the JWT to the initial SockJS HTTP handshake request. Do you think I should use a different store type, and not `LocalSessionStore`? – foxtrotuniform6969 Jan 12 '21 at 13:39

1 Answers1

1

I'm using the following straight-forward code to keep the session-like information available:

class SockJSBridge implements Handler<BridgeEvent> {

  @Override
  void handle( BridgeEvent event ) {
    
    SockJSSocket socket = event.socket()
    MultiMap headers = socket.headers()

    switch( event.type() ){
      case REGISTER:
         def user = getUserFromJWTHeader event.rawMessage.headers.authorization
         headers.add 'userId', user.id
         break

      case SEND:
         String userId = headers.get 'userId'
         socket.write new JsonObject( address:userId, body:event.rawMessage?.body ).toBuffer()
         break
     }
  }
}

injecteer
  • 20,038
  • 4
  • 45
  • 89
  • Sweet, looks straight forward. How are you going about adding the headers on the client side? Doesn't look like `sockjs-client` supports headers – foxtrotuniform6969 Jan 12 '21 at 14:17
  • it's not the sockjs-client not supporting headers, but rather the websocket itself. See https://github.com/sockjs/sockjs-client/issues/196. That's why I had to 1st establish the "unsecured" connection, and then sent headers with the 1st message body – injecteer Jan 12 '21 at 14:39
  • That's kinda what I was doing too, but my implementation was much more complex and buggy. How do you go about setting the bridge event type on the client side? – foxtrotuniform6969 Jan 12 '21 at 14:43
  • I don't. I'm just using the `eventBus.registerHandler()` and `eventBus.send()` methods which set the event type in a default fashion – injecteer Jan 12 '21 at 14:47
  • Interesting... I'm not seeing the same behavior when following [this part](https://vertx.io/docs/vertx-web/java/#_sockjs_event_bus_bridge) (scroll down to the JS side's `registerHandler`. My server only ever sees `SOCKET_CREATED` and never `REGISTER` nor `SEND` – foxtrotuniform6969 Jan 12 '21 at 15:05
  • I think you should open another question about the client... – injecteer Jan 13 '21 at 11:03
  • I had thought about it, but the problem is that the two are very closely related. – foxtrotuniform6969 Jan 13 '21 at 13:15