Correct way of dealing with get request parameters

Specific use cases:

  • “forgot my password” account restore token
  • “verify it’s my e-mail address” token

User gets an email with a request like abc.com/?token=abcdef

User clicks the link and the system processes the token.

What I have so far: (this code is in the LoginScreen class)

@Subscribe
private fun onInit(event: InitEvent) {

    val handleVaadinRequestFunction: (session: VaadinSession, request: VaadinRequest, response: VaadinResponse) -> Boolean =
        { session, request, response -> handleVaadinRequest(request) }

    AppUI.getCurrent()?.let { ui ->
        // Handle current request
        VaadinRequest.getCurrent()?.let { currentRequest ->
            handleVaadinRequest(currentRequest)
        }
        // Handle future requests on initialized UI
        //   https://vaadin.com/docs/v7/framework/advanced/advanced-requesthandler
        ui.session.removeRequestHandler(handleVaadinRequestFunction)
        ui.session.addRequestHandler(handleVaadinRequestFunction)
    }
}

private fun handleVaadinRequest(request: VaadinRequest?): Boolean {
    request?.getParameter("resetpasswordtoken")?.let { token ->
        log.info("resetpasswordtoken retrieved: $token")
        // ... do some stuff with the token
    }
}

This works unreliably and I don’t know why. As this is a quite common use case, I wonder if there is a “proper” way of doing it?

Hi,
You need to listen to the UrlParamsChangedEvent.

Docs: Screen Events :: Jmix Documentation

See working sample here: https://github.com/Haulmont/jmix-quickstart/blob/security-advanced-complete/src/main/java/com/company/jmixpm/screen/public_/useractivation/UserActivation.java

Thanks, I tried to change the code to use the UrlParamsChangedEvent but the method is never called.

I removed the code from my first post and added:

@Subscribe
private fun onUrlParamsChanged(event: UrlParamsChangedEvent) {
    event.params["resetpasswordtoken"]?.let { token ->
        log.info("resetpasswordtoken retrieved: $token")
        // ... do some stuff with the token

This is all in the LoginScreen - does that make any difference maybe?

Can you try if it will work with Java, or at least make the method public?
I have not tested with Kotlin.

Another idea: you should specify the screen route for the login screen:

@Route(value = “login”, root = true)

and provide user with the link “abc.com/#login?token=abcdef
Maybe request parameters are lost during the redirect?..

1 Like

Indeed, the route was already set, but I didn’t use it in the URL. So when adding #login to it, everything works now, thank you!