"Нет провайдера для AuthGuard!" использование CanActivate в Angular 2

РЕДАКТИРОВАТЬ: Очевидно, что это устарело, теперь вы обеспечиваете свою защиту в массиве providers в NgModule. Смотрите другие ответы или официальную документацию для получения дополнительной информации.

  • начальная загрузка компонента устарела
  • provideRouter() устарел


Я пытаюсь настроить Аутентификацию в своем проекте, используя имя пользователя и AuthGuard из руководства Angular2: 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, который загружает заголовок, содержащий кнопки, которые позволяют мне перемещаться по моему приложению, и он также содержит мой основной на данный момент.

Я следую руководству, чтобы сделать мое приложение таким же образом со следующим 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 есть собственное определение маршрута, которое также содержит охрану, которую я пытаюсь настроить. master.routes.ts:

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

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

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

И я использую те же файлы, что и руководство, которые являются auth.guard.ts, auth.service.ts, login.component.ts и login.routes.ts.


В моем файле header.component.ts, когда я пытаюсь получить доступ к любым маршрутам, он работает просто отлично, но когда я пытаюсь получить доступ к защищенному пути (/dashboard), я получаю провайдера No для AuthGuard! ошибка.

Я видел недавний пост с той же проблемой, что и у меня (NoProviderError использует CanActivate в Angular 2), но для меня защита правильно загружена до файла main.ts, поэтому мой маршрутизатор должен знать, какие маршруты должны быть предоставлены с правом AuthGuard?

Любая помощь или совет будет принята с благодарностью. Спасибо !

Ответы

Ответ 1

Собственно, это была только опечатка в импорте...

Я печатал

import {AuthGuard} из './../Authentification/auth.guard';

вместо

import {AuthGuard} из './../authentification/auth.guard';

чтобы он не работал, но в то же время не отображал мне никакой ошибки...

(sadface)

Ответ 2

У меня была такая же проблема после прохождения раздела "Маршрутные гвардии" руководства по маршрутизации и авторизации на веб-сайте Angular https://angular.io/docs/ts/latest/guide/router.html, это раздел 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 к провайдерам, не знаю почему.

Ответ 3

Кроме того, не попадайте в ловушку использования литерала для класса защиты внутри вашей конфигурации маршрутизации, просто потому, что некоторые статьи в блоге:

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

не будет работать (No provider for...), вместо этого используйте класс напрямую:

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

Другой намек, когда ленивые компоненты загрузки, защита применяется в конфигурации маршрутизации родительского компонента, а не в конфигурации маршрутизации ленивого загруженного компонента.

Ответ 4

Для тех, у кого еще есть эта ошибка, не забудьте включить службу или класс 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

Ответ ниже в уроке. См. Список файлов в разделе "Добавить входной компонент" в разделе "Некоммерческий маршрут:..." в разделе "Веха 5: Маршрутные охранники". Он показывает, что AuthGuard и AuthService импортируются и добавляются в массив поставщиков в login-routing.module.ts, а затем этот модуль импортируется в 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
  ],
  ...

Ответ 6

Я столкнулся с этой проблемой, когда я следил за учебником. Я пробовал большую часть ответа здесь, но не добился успеха. Затем я попробовал глупый способ, как положить AuthGuard перед другими службами в провайдере, и он работает.

// app.module.ts

 .. 
 providers: [
   AuthGuard,
   UserService,
   ProjectService
  ]

Ответ 7

Поскольку у вас есть решение, так как это связано с проблемой синтаксиса. Я просто хотел поделиться этой информацией.

нам нужно предоставить 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{}    

Ответ 8

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;
    }
}

Ответ 9

Мне помогли импортировать как HttpModule, так и HttpClientModule.

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

Ответ 10

вы можете попробовать импортировать AuthGuard в провайдер этого модуля, а затем импортировать его в файл маршрутизации-routing.module.ts также

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

Ответ 11

Попробуй добавить

@Injectable({ providedIn: 'root' }) нет необходимости добавлять к поставщику модуля.