You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CanActivate guards on child routes run before parent CanActivate guards finish #15670
[X] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
When both a route and it's parent have an asynchronous canActivate guard, and the child is navigated to directly, both guards are run at same time.
Expected behavior
The parent's canActivate guard should run before the child's guard. If the parent's guard is unsuccessful the child guard should not be run. If a route defines multiple canActivate guards, those can/should be run in parallel.
Plunker has a nested route /parent/child. Both have guards that simply wait and then return true. Each guard logs its start/end as well as a tick once per second to a logging service that is displayed in the root component.
Click 'Go to Child` to trigger both the Parent Guard and the Child guard at the same time, and observe that they process simultaneously in the log.
What is the motivation / use case for changing the behavior?
In my athepp, ParentGuard checks to see if the user is authenticated and redirects accordingly, and ChildGuard loads protected data. Right now, my child guard cannot assume the user is logged in, so I have to duplicate logic from the authorization guard to wait for the user to be loaded. When I have a grandchild route, that has to duplicate logic from two parent guards. I would like to be able to separate concerns more rather than duplicate auth logic in all my guards.
inject the parent's guard into the child guard. You can promisify that one (or if it already returns a promise), call that one to finish then do your child guard. Pros: Not too difficult to implement. Cons: If your parent calls the guard as well, you are calling the guard twice. In addition, you have a race condition, and if the failure causes a redirect, this could be bad.
Get rid of the hierarchical guard structure. For example if you have a loggedInGuard and a userIsAdmin guard, make a new guard called userIsLoggedInAndIsAdmin. I hate this solution, but maybe a good workaround for some cases. This becomes more unmaintainable as you increase the number of guards you have.
Ultimately, the guards should have an easy way to signal each other that they finished their run and what the outcome is.
I'm waiting for the final resolution of this as well. Having child guards call parent guards is not a suitable option. I'm surprise that there has not been movement of this. This seems to be a significant problem.
please help me, how to add role on user in firebase?
Reacted by Trotyl Yu, v, Tiberiu Oprea, Stephanos, patricknazar, Eman Jasarevic, Rafael Kraut, José Toledo Navarro, Gabriel Savoie, Damien Retzinger and 20 more
Yup just ran into this also. My child guards rely on the results of the parent resolver which seems reasonable. Being able to make decisions on the children based on data coming back seems like a pretty standard use case.
Activity
jdell64 commentedon May 13, 2017
Did you find a work around?
Drabc commentedon Jun 7, 2017
I'm facing the same issue. I have an
AuthGuardwhich is setting application state thatchildGuardsdepend on.Something similar happens with
canLoad. However,canLoadseems to be running before theparentGuardgets called.The documentation does not specify that
childGuardsshould wait forparentGuards, so is this intended behavior? How should this be done?jdell64 commentedon Jun 9, 2017
These are the workarounds I found
inject the parent's guard into the child guard. You can promisify that one (or if it already returns a promise), call that one to finish then do your child guard. Pros: Not too difficult to implement. Cons: If your parent calls the guard as well, you are calling the guard twice. In addition, you have a race condition, and if the failure causes a redirect, this could be bad.
Get rid of the hierarchical guard structure. For example if you have a
loggedInGuardand auserIsAdminguard, make a new guard calleduserIsLoggedInAndIsAdmin. I hate this solution, but maybe a good workaround for some cases. This becomes more unmaintainable as you increase the number of guards you have.Ultimately, the guards should have an easy way to signal each other that they finished their run and what the outcome is.
kevinvanhove commentedon Jun 14, 2017
You need to add a CanActivateChild method to your guard: https://angular.io/guide/router#canactivatechild-guarding-child-routes
... no, that's not it... doesn't work...
jnapier commentedon Jun 21, 2017
The fix by @DzmitryShylovich seems to fix this issue. Are there any plans for this to be released? There has been no movement for a few months.
kevinvanhove commentedon Jun 22, 2017
I solved it by using 2 promises, where the childs canActivate method waits for the parents guard promise to resolve?
Drabc commentedon Jun 23, 2017
I'm waiting for the final resolution of this as well. Having child guards call parent guards is not a suitable option. I'm surprise that there has not been movement of this. This seems to be a significant problem.
onurcipe commentedon Jul 12, 2017
Same here...
This behaviour causes an important security bug in our software. Any news or dates about fixing the issue?
fix(router): child CanActivate guard should wait for parent to complete
fix(router): child CanActivate guard should wait for parent to comple…
fix(router): child CanActivate guard should wait for parent to comple…
fix(router): child CanActivate guard should wait for parent to comple…
fix(router): child CanActivate guard should wait for parent to comple…
iBeriaLab commentedon Oct 31, 2017
please help me, how to add role on user in firebase?
lppedd commentedon Jun 21, 2019
Please re-open and re-consider. This is not fixed and it's really a big problem.
brandon-sigao commentedon Jul 9, 2019
Yup just ran into this also. My child guards rely on the results of the parent resolver which seems reasonable. Being able to make decisions on the children based on data coming back seems like a pretty standard use case.
richardsengers commentedon Aug 6, 2019
SAme thing here ... to me it looks very common to use data from a resolver to the child guard...please reconsider
angular-automatic-lock-bot commentedon Sep 15, 2019
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.