Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Routing: Query parameters for CanLoad guard not available #12411

Closed
adoris opened this issue Oct 20, 2016 · 20 comments
Closed

Routing: Query parameters for CanLoad guard not available #12411

adoris opened this issue Oct 20, 2016 · 20 comments
Labels
area: router effort1: hours feature Issue that requests a new feature
Milestone

Comments

@adoris
Copy link

adoris commented Oct 20, 2016

I'm submitting a ... (check one with "x")

[] bug report => search github for a similar issue or PR before submitting
[x] feature request
[ ] support request =>

Current behavior
I try to implement simple app with silent login via auth token (sessionId). If no sessionId provided- fallback to login via username/password.
If i try to navigate to component from synchronously loaded module - in can be protected with CanActivate guard - we have ActivatedRouteSnapshot with query parameters. If i try to navigate to a lazily loaded component - it is prtoected with CanLoad guard.
CanLoad guard has no access query parameter (?&) or parameter in matrix notation(;) from browser address string - has no ActivatedRouteSnapshot parameter.

Expected behavior
i expect, that query parameters (or matrix notation parameters) are available in CanLoad guard via ActivatedRoute parameter.

Minimal reproduction of the problem with instructions
http://plnkr.co has no possibility to use many html pages -> i have prepared modified sample of heroes app from tutorial https://angular.io/docs/ts/latest/guide/router.html.
Modified sample can be found at https://github.com/adoris/tour-of-heroes

  1. load and prepare app from: https://github.com/adoris/tour-of-heroes.git
  2. ng serve
  3. call browser http://localhost:4200/index_angular2.html
  4. use any link. First link works as expected with login page.
    All other links must be processed without login page, but login page displayed.

If I call app with this links from my sample app - i want to proceed without login-screen:
http://localhost:4200/hero/13?SessionId=98765&Extras1=testextras
http://localhost:4200/heroes;id=13;SessionId=98765;Extras1=testextras

Please tell us about your environment:
angular-cli, windows, vs code.

  • Angular version: 2.1.0
@DzmitryShylovich
Copy link
Contributor

#11023

has no possibility to use many html pages

that's not true.

@adoris
Copy link
Author

adoris commented Oct 20, 2016

i use official sample http://run.plnkr.co/6XSNCCpgbS1BzqtW/ from tutorial at https://angular.io/docs/ts/latest/guide/router.html.
if i "Launch the preview in a sepatated window" - following link works if navigated from app, but fails if called direct:
http://run.plnkr.co/6XSNCCpgbS1BzqtW/hero/13

@adoris adoris changed the title Route on root component loses query parameters. Query parameters for CanLoad guard not available Oct 21, 2016
@adoris adoris changed the title Query parameters for CanLoad guard not available Routing: Query parameters for CanLoad guard not available Oct 21, 2016
@vsavkin vsavkin added feature Issue that requests a new feature effort1: hours severity2: inconvenient labels Oct 31, 2016
@vsavkin
Copy link
Contributor

vsavkin commented Oct 31, 2016

@adoris we cannot provide an ActivatedRoute to a canLoad guard because CanLoad guards haven't been constructed at this point. What we can provide instead is a UrlTree.

@oexza
Copy link

oexza commented Nov 25, 2016

I face this same problem and have no idea what alternative there is.

marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Nov 29, 2016
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
@marcuskrahl
Copy link
Contributor

I submitted a pull request which adds url segments to the CanLoad interface. The ActivatedRouteSnapshot is unfortunately not available at this stage in the routing call, but the url segment array should be fine for common usage, e.g. router.navigate(urlSegments);

marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Nov 29, 2016
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
@fbobbio
Copy link

fbobbio commented May 3, 2017

@marcuskrahl what's the status of this? I see the PR was never merged

@marcuskrahl
Copy link
Contributor

@fbobbio unfortunately no response from the angular devs. I might update the pull request and ping the devs again soon.

@jhuntoo
Copy link

jhuntoo commented May 13, 2017

Hi I've just run into this problem... I want to store the current url, so that I can redirect to it after a successful login. For now I'm relying on canActivate.. which means sometimes a lazy module is loaded unnecessarily.. which isn't ideal.

@marcuskrahl Do you know which angular dev to ping for router PRs ?

@XavierLevaux
Copy link

I want to do this too, so let's hope this move on

@figuerres
Copy link

I think i am also having a problem here....

user is on a view where they are not authenticated, no token , anon user.
the view needs to send them to a protected view in a module

the module has a "CanLoad" that can see they are not logged in and redir the user to get a token.
in the CanActivate this works as it gets the target route and passes that as a parameter to the token server who will pass it back to finish the job.
but i do not seem to find that target route in CanLoad.
so no canload ?? just use CanActivate ??

@figuerres
Copy link

a note on this: something know that the app is trying to navigate the user to a module, so the router.Navigate call has the target route and had to figure out that it went to a route that needed a module load.
i think that if that navigate call parameter was saved and passed to the can load call from there was can code the rest of the way....

@figuerres
Copy link

@vsavkin

i feel that this is a core flaw in the router / lazy load and needs to be at a more urgent priority.
while this is early in the route process it is a common case to need to know what the requested URL is and it is also common to several authentication cases that we may need to do a redirection or other actions that might re-load the app before we can proceed.
an example is if you use Identity server with the implicit flow, that requires that the app calls the identity server which does a redirect back to the app this is an app reload.
this works with the can activate guard but now with the can load guard.
https://github.com/IdentityServer

the sts handles the user login UI and this keeps the app from knowing the users password, this is also used to allow for sign on with Facebook, Google, Twitter and Microsoft accounts via OIDC / OAuth 2

so not having some kind of router state (whatever the details may be) that we can pass to the sts makes can load non usable for users of this type of login method to get a user token.

the workaround of using can activate means that modules do not lazyload based on security rules.
so this is not a good situation.

the basic library for using identity server with angular is https://github.com/IdentityModel/oidc-client-js

and it works with can activate perfectly in my app. i pass a state object on calling for a token and it returns it on the return trip, i can then make a navigate call to the router to get back to the url the user was trying to go to at the start.

if we need a different kind of state object that can be done, just need a definition to work with.

jasonaden added a commit to jasonaden/angular that referenced this issue Jul 16, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl pushed a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jul 19, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Aug 2, 2017
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
@broweratcognitecdotcom
Copy link

broweratcognitecdotcom commented Oct 18, 2017

We also have a requirement where this stops us. We want to send URLs in emails. When user clicks a link and their browser loads the angular app, with a url to a lazy loaded module, there is no way to navigate to Login with a return Url from CanLoad if CanLoad fails the authentication check. In addition to this, lazy modules can get loaded even when the user is not authenticated. CanActivate in the lazy routes still boots them back to Login, but I strongly believe that CanLoad needs the same or similar args as CanActivate.

@shaungrady
Copy link
Contributor

Would also love to see this solved.

marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Jan 14, 2018
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
@ngbot ngbot bot added this to the Backlog milestone Jan 23, 2018
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Mar 29, 2018
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
marcuskrahl added a commit to marcuskrahl/angular that referenced this issue Mar 29, 2018
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411
@picosam
Copy link

picosam commented Apr 1, 2018

Any idea when the PR will be merged?

@kublaios
Copy link

kublaios commented May 3, 2018

I am waiting for the merge too, or at least this issue to get to a final point.

@felixhayashi
Copy link

Need this to store the redirect url after login.
So far, I am forced to only employ canActivate in order to have access to the router state...

@RGVGreatCoder
Copy link

RGVGreatCoder commented May 24, 2018

My "temporary" workaround is saving the URL as follows:

 public canLoad(route: Route): boolean | Observable<boolean> | Promise<boolean> { 
    let url = window.location.pathname; 
    if (this.authServ.isLoggedIn) return true;
    // Store the attempted URL for redirecting
    localStorage.setItem('returnUrl', url);
    // Navigate to the login page with extras
    this.authServ.login(); // Call auth end point using IdentityServer4
    return false;
 }

When auth end point calls back, I run the following code:

ngOnInit() {
    this.authServ.isAuthorized().subscribe(() => {
        if (this.authServ.isLoggedIn) {
            let redirectUrl: string | null = localStorage.getItem('returnUrl');
            redirectUrl = redirectUrl ? redirectUrl : '/admin';
            localStorage.removeItem('returnUrl');
            this.router.navigate([redirectUrl]);
        }
    })
}

Hope RouterStateSnapshot is added soon to CanLoad in @angular/router

@felixhayashi
Copy link

@RGVGreatCoder the problem with this solution is that your canLoad now depends on window.location.pathname

FrederikSchlemmer pushed a commit to FrederikSchlemmer/angular that referenced this issue Jan 3, 2019
CanLoad now defines UrlSegment[] as a second parameter of the function.
Users can store the initial url segments and refer to them later, e.g. to go
back to the original url after authentication via router.navigate(urlSegments).
Existing code still works as before because the second function parameter
does not have to be defined.

Closes angular#12411

PR Close angular#13127
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: router effort1: hours feature Issue that requests a new feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.