簡體   English   中英

“沒有 AuthGuard 的提供者!” 在 Angular 2 中使用 CanActivate

[英]“No provider for AuthGuard!” using CanActivate in Angular 2

編輯:顯然這已經過時了,現在您在 NgModule 中的providers數組中提供保護。 觀看其他答案或官方文檔以獲取更多信息。

  • 組件上的引導已過時
  • provideRouter()也已過時


我正在嘗試使用 Angular2 指南中的登錄名和 AuthGuard 在我的項目中設置身份驗證: https ://angular.io/docs/ts/latest/guide/router.html

我正在使用發行版:“@angular/router”:“3.0.0-beta.1”。

我會盡量解釋清楚,如果您需要更多細節,請隨時告訴我。


我有我的main.ts文件,它使用以下代碼增強應用程序:

bootstrap(MasterComponent, [
    APP_ROUTER_PROVIDERS,
    MenuService
])
.catch(err => console.error(err));

我加載了 MasterComponent,它加載了一個 Header,其中包含允許我瀏覽我的應用程序的按鈕,它現在還包含我的 main。

我正在按照指南使我的應用程序以相同的方式工作,並使用以下app.routes.ts

export const routes: RouterConfig = [
    ...LoginRoutes,
    ...MasterRoutes
];

export const APP_ROUTER_PROVIDERS = [
    provideRouter(routes),
    AUTH_PROVIDERS
];

指南中的login.routes.ts定義了我的 AuthGuard :

export const LoginRoutes = [
    { path: 'login', component: LoginComponent }
];

export const AUTH_PROVIDERS = [AuthGuard, AuthService];

我的主組件有自己的路由定義,其中還包含我試圖設置的守衛。 master.routes.ts

export const MasterRoutes : RouterConfig = [
    { path: '', redirectTo: '/accueil', pathMatch: 'full' },

    {
        path: 'accueil',
        component: AccueilComponent
    },

    { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
];

我使用與指南相同的文件,即auth.guard.tsauth.service.tslogin.component.tslogin.routes.ts


在我的header.component.ts文件中,當我嘗試訪問任何路由時,它工作得很好,但是當我嘗試訪問受保護的路徑 (/dashboard) 時,我得到了AuthGuardNo provider! 錯誤。

我看到最近的帖子與我的問題相同( 在 Angular 2 中使用 CanActivate 的 NoProviderError ),但對我來說,守衛被正確引導到main.ts文件,所以我的路由器應該知道應該為哪些路由提供 AuthGuard 權限?

任何幫助或建議將不勝感激。 謝謝!

在瀏覽了 Angular 網站https://angular.io/docs/ts/latest/guide/router.html上的路由和授權教程的 Route Guards 部分后,我遇到了同樣的問題,它是第 5 部分。

我將 AuthGuard 添加到我的主要路由之一,而不是像教程所示的子路由。

我通過將 AuthGuard 添加到我的 app.module.ts 文件中的提供程序列表來修復它,因此該文件現在看起來像這樣:

import { AppComponent } from './app.component';
import {AppRoutingModule} from './app-routing.module';
import {AuthGuard} from './auth-gaurd.service';

import { AnotherPageComponent } from './another-page/another-page.component';
import { LoginPageComponent } from './login-page/login-page.component';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    JsonpModule,
    AppRoutingModule,
    HttpModule
  ],
  declarations: [
    AppComponent,
    LoginPageComponent,
    AnotherPageComponent
  ],
  providers: [AuthGuard],
  bootstrap: [AppComponent]
})

export class AppModule { }

我已經回顧了教程,在他們的 app.module.ts 文件中,他們沒有向提供者添加 AuthGuard,不知道為什么。

另外,不要陷入在路由配置中為保護類使用文字的陷阱,僅僅因為一些博客文章這樣做:

{ path: 'whatever', component: WhatEverComponent, canActivate: ['WhatEverGuard'] }

不會工作( No provider for... ),而是直接使用該類:

{ path: 'whatever', component: WhatEverComponent, canActivate: [WhatEverGuard] }

另一個提示,當延遲加載組件時,guard 應用在父組件的路由配置中,而不是延遲加載組件的路由配置中。

嘗試添加

@Injectable({ providedIn: 'root' })不需要添加到模塊提供者。

對於那些仍然有這個錯誤的人 - 不要忘記將你的 AuthGuard 服務或類包含到主引導函數中。 並且不要忘記在引導程序運行之前導入此服務。

import { bootstrap } from '@angular/platform-browser-dynamic';

import { AppComponent } from './app.component';
import { AuthGuard } from './shared/auth.service';

bootstrap(AppComponent, [
  appRouterProviders,
  AuthGuard
]);

Angular 2 團隊在主要路由器文檔中沒有提到這一點,我花了幾個小時才弄明白。

答案在教程的后面。 請參閱“里程碑 5:路由保護”中“無組件路由:...”部分下“添加 LoginComponent”主題中的文件列表。 它顯示了 AuthGuard 和 AuthService 被導入並添加到 login-routing.module.ts 中的 providers 數組,然后該模塊被導入到 app.module.ts 中。

登錄-routing.module.ts

  ...
    import { AuthGuard }            from './auth-guard.service';
    import { AuthService }          from './auth.service';
    ...
    @NgModule({
    ...
      providers: [
        AuthGuard,
        AuthService
      ]
    })
    export class LoginRoutingModule {}

app.module.ts

import { LoginRoutingModule }      from './login-routing.module';

@NgModule({
  imports: [
    ...
    LoginRoutingModule,
    ...    
  ],
  ...
  providers: [
    DialogService
  ],
  ...

實際上,這只是導入中的一個錯字...

我在打字

從 './../Authentification/auth.guard' 導入 { AuthGuard };

而不是

從 './../authentication/auth.guard' 導入 { AuthGuard };

使它不工作,但同時不顯示任何錯誤...

(悲傷的臉)

我在學習教程時遇到了這個問題。 我在這里嘗試了大部分答案,但沒有取得任何成功。 然后我嘗試了愚蠢的方法,例如將 AuthGuard 放在提供程序中的其他服務之前,並且它有效。

// app.module.ts

 .. 
 providers: [
   AuthGuard,
   UserService,
   ProjectService
  ]

既然你得到了解決方案,因為它是由於語法問題。 我只是想分享這個信息。

我們只需要在對應於相應路由的那個模塊中提供 AuthGaudSerivce 作為提供者。 無需在主模塊或根模塊中提供,因為主模塊會自動加載所有給定的子模塊。這有助於保持代碼模塊化和封裝。

例如,假設我們有以下場景

1. we have module m1
2. we have route m1r in module m1
3. route m1r has 2 route r1 and r2
4. we want to protect r1 using authGaurd
5. finally we have main module that is dependent on sub module m1 

以下只是原型,不是用於理解目的的實際代碼

//m1.ts    
import {AuthGaurd} from './auth.gaurd.service'
import {m1r} from './m1r'
    @NgModule(
     imports: [m1r],
     providers: [AuthGaurd]
    )
    export class m1{
    }

//m1r.ts
import {AuthGaurd} from './auth.gaurd.service'
const authRoute = [
 {path: '/r1', component: 'authComponent', canActivate: [AuthGaurd]},
 {path: '/r2', component: 'other'}
]
export authRoute

//main.module.ts
import {m1} from ''
import {mainComponent} from ''
@NgModule({
  imports: [m1],
  bootstrap: [mainComponent]
  })
export class MainModule{}    
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(private router: Router) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        if (localStorage.getItem('currentUser')) {
            // logged in so return true
            return true;
        }

        // not logged in so redirect to login page with the return url
        this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
        return false;
    }
}

導入HttpModuleHttpClientModule對我HttpClientModule幫助。

import { HttpClientModule } from '@angular/common/http'; 
import { HttpModule } from '@angular/http';

您可以嘗試在該模塊的提供者中導入 AuthGuard,然后也將其導入到路由 component-routing.module.ts 文件中

@NgModule({
providers: [
    AuthGuard
  ],})

當我錯誤地設置我的路線時,這發生在我身上:

const routes: Routes = 
[
  { 
    path: 'my-path', 
    component: MyComponent, 
    resolve: { myList: MyListResolver, canActivate: [ AuthenticationGuard ] } 
  },
];

請注意,在這種情況下, canActivate意外地成為resolve對象的一部分。

正確

const routes: Routes = 
[
  { 
     path: 'my-path', 
     component: MyComponent, 
     resolve: { myList: MyListResolver }, 
     canActivate: [ AuthenticationGuard ] 
  },
];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM