"Нет провайдера для 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' })
нет необходимости добавлять к поставщику модуля.