GManProgram
GManProgram

Reputation: 161

Remove previous query strings on router redirect

My aurelia application has two roots, an app-login and the app root. When users try to access the application and are not logged in, they are sent to the app-login route, which only has 1 route configured, login.

If an unauthenticated user tries to access the app as though they were logged in, (e.g. localhost:3000/#/needsAuthenticationRoute), I want the user to be taken to the login page, however, upon successfully logging in, have them be redirect to the page they were initially trying to access.

I try to handle the issue as follows:

config.mapUnknownRoutes((instruction) => {
  let redirectUrl = 'login';
  console.log(instruction);

  if(instruction.fragment !== '/') {
    let redirect = instruction.fragment;
    if(instruction.queryString) {
      redirect = redirect + '?' + instruction.queryString;
    }
    redirectUrl = router.generate('login', {redirect});
  }
  return {redirect: redirectUrl };
});

So from the app-login route, if they try to access needsAuthenticationRoute, they would be redirected back to the login page with a redirect parameter (the user would be sent to localhost:3000/#/login?redirect=%2FneedsAuthenticationRoute in this case).

However, when the user tries to access a route with a query string (e.g. needsAuthenticationRoute?param=value), I would want the user to be redirected to localhost:3000/#/login?redirect=%2FneedsAuthenticationRoute%3Fparam%3Dvalue. However, the redirect keeps around the query parameter and I am left with a route that looks like localhost:3000/#/login?redirect=%2FneedsAuthenticationRoute%3Fparam%3Dvalue?param=value.

Does anybody know how to clear query the query params when specifying a redirect instruction? Or have an alternative solution to what I am proposing?

Upvotes: 2

Views: 763

Answers (1)

ry8806
ry8806

Reputation: 2328

I have recently just implemented the exact functionality you describe (I also have a blog post in draft about this topic too - when I get round to publishing it...)

I have a bunch of routes, some that have query strings, some which don't. If the user isn't logged in i want to redirect them to the login page, then after successful login I want to redirect them to where they were going before.

Also, I wanted to keep the "?returnUrl=" query string out of the url, it works, but just felt a bit messy to me - considering that this is all client side routing, i knew i could store it somewhere and "hide" it/

So firstly, we need to stash the route they were going to before login, this is done in a defined AuthorizeStep Aurelia AuthorizeStep

@inject(MyApi)
class AuthorizeStep implements PipelineStep {
    constructor(private api: MyApi) { }

    public run(navigationInstruction: NavigationInstruction, next: Next): Promise<any> {
        if (navigationInstruction.getAllInstructions().some(i => i.config.settings.roles.indexOf("Client") !== -1)) {
            if (!this.api.LoggedIn && navigationInstruction.config.name !== "login") {
                this.api.RouteFragment = navigationInstruction.fragment;
                return next.cancel(new Redirect("login"));
            }
        }
        return next();
    }
}

Finally, the login page needs to be made aware that after logging in, the user might be going somewhere. So after a successful login we check to see if anything has been stashed in the RouteFragment

if (loginResult.Success) {
    if (this.api.RouteFragment && this.api.RouteFragment.length > 0) {
        // Navigate to where the user was trying to go before Logging In
        this.router.navigate(this.api.RouteFragment);
    } else {
        this.router.navigate("/dashboard");
    }
}

Upvotes: 0

Related Questions