简体   繁体   English

为什么 Angular 守卫在 ngOnInit 之前运行?

[英]Why Angular guard is running before ngOnInit?

I have checkAuth function in ngOnInit in app.component.ts which checks localStorage for token and if token is valid authService logs you in.我在checkAuthngOnInit中有 checkAuth app.component.ts检查 localStorage 中的令牌,如果令牌有效 authService 会登录。

Also, I have AuthGuard in /profile route which checks if you logged in.另外,我在/profile路由中有 AuthGuard,它会检查您是否登录。

If I click the link in the navbar this works great, but if I go to link directly authGuard working before my checkAuth function and returns false.如果我单击导航栏中的链接,效果很好,但如果我 go 直接链接 authGuard 在我的checkAuth function 之前工作并返回 false。

Where do I need to place my checkAuth function to make it work correctly?我需要将我的checkAuth function 放在哪里才能使其正常工作? Or maybe I need to change something in AuthGuard or in app.component或者我可能需要在 AuthGuard 或 app.component 中更改某些内容

Here is AuthGuard code这是 AuthGuard 代码

@Injectable({
  providedIn:'root'
})
export class AuthGuard implements CanActivate, CanActivateChild {

  constructor(private auth:AuthService, private router:Router) {
  }

  canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>{
    console.log(this.auth.isAuth)
    console.log(this.auth.isLoggedIn())
    if (this.auth.isLoggedIn()){
      return of(true)
    } else {
      this.router.navigate(['/login'])
      return of(false)
    }
  }

  canActivateChild(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>{
    return this.canActivate(route, state)
  }
}

app.component应用程序组件

ngOnInit() {
    if (localStorage.getItem('token')){
      this.auth.checkAuth().subscribe(
        (data) => {
          console.log(data)
          console.log(this.auth.isAuth)
        }
      )
    }
  }

and checkAuth in AuthService并在 AuthService 中检查Auth

checkAuth():Observable<UserDto>{
     return this.http.get<UserDto>(`/api/user/refresh`, {withCredentials:true, observe:'body', responseType:'json'})
        .pipe(
          tap(
            (data) => {
              localStorage.setItem('token', data.accessToken)
              this.setAuth(true)
              this.setUser(data.user)
            },
            (error) => {
              console.log(error)
            }
          )
        )
  }

If you want checkAuth to run before the guard, you have to make it a guard as well, and use it before the guard that you already have.如果你想让checkAuth在守卫之前运行,你也必须让它成为守卫,并在你已经拥有的守卫之前使用它。 Eg: canActivate: [CheckAuthGuard, AuthGuard] .例如: canActivate: [CheckAuthGuard, AuthGuard]

This is what's going on right now:这就是现在发生的事情:

First scenario - accessing /profile by clicking in the navbar第一种情况 - 通过单击导航栏访问/profile

  1. You access the application's root component您访问应用程序的根组件
  2. Whatever guards you have on the root route run无论您在根路由上使用什么守卫
  3. The root component is initialized and AppComponent.ngOnInit() runs, thus running checkAuth()根组件被初始化并且AppComponent.ngOnInit()运行,因此运行checkAuth()
  4. You click the link in the navbar to go the /profile route您单击导航栏中的链接到 go /profile路由
  5. Guards for the profile route are run运行配置文件路由的守卫

Second scenario - accessing /profile by visiting the URL directly第二种情况 - 通过直接访问 URL 来访问/profile

  1. You access the application's root component, but this time it is routed to the /profile route您访问应用程序的根组件,但这次它被路由到/profile路由
  2. Whatever guards you have on the profile route run无论您在配置文件路线上拥有什么守卫
  3. The root component and it's child are initialized, running their ngOnInit() methods初始化根组件及其子组件,运行它们的ngOnInit()方法

See?看? In the second scenario, the guard runs before ngOnInit and checkAuth .在第二种情况下,守卫在 ngOnInit 和checkAuth之前运行。 I advise you to put some console.log calls on your app, so you can more easily see the order in which things are happening.我建议你在你的应用程序上调用一些console.log ,这样你就可以更容易地看到事情发生的顺序。

Basically this is it, guards run before the component is rendered, so you should keep that in mind.基本上就是这样,防护在组件渲染之前运行,所以你应该记住这一点。 Extract your checkAuth call to a guard and you'll be fine.将您的checkAuth呼叫提取给警卫,您会没事的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM