Reputation: 161
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
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