«Нет поставщика для 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.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), я получаюНет поставщика для AuthGuard! ошибка.

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

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

 Alex Beugnet05 июл. 2016 г., 16:09
Да, нашел это ... черт ... потерять 2 часа из-за этого ...
 Alex Beugnet05 июл. 2016 г., 14:51
Да, работает правильно, хотя я заметил следующее предупреждение:'AccueilComponent' не найден в массиве прекомпиляции. (и то же предупреждение для DashboardComponent, когда я перемещаюсь, нажимая на мою кнопку)
 Alex Beugnet05 июл. 2016 г., 14:46
Да, я использую файл auth.guard.ts из руководства, с authService и маршрутизатором в DI в конструкторе. Также есть декоратор. Это точно такой же файл, какapp / auth.guard.ts (v.2) от гида
 Alex Beugnet05 июл. 2016 г., 16:01
plnkr.co/edit/iDghZJNl1hL7UQM1MEsC?p=preview  Я не понимаю ... Он работает на плунжере, хотя это то же самое без CSS и изображений ... Я думаю, мне нужно искать в моем собственном коде причину ...
 Alex Beugnet05 июл. 2016 г., 14:42
Да, я импортировал их правильно. Я не упомянул об этом, но я вручную перехожу к маршруту, потому что я хотел сделать ссылку на кнопку <button>, используяthis.router.navigate ([ '/ панель']);
 Alex Beugnet05 июл. 2016 г., 15:13
Странно то, что брандмауэр моей компании на самом деле блокирует ссылки на plunkr, поэтому мне может понадобиться немного времени ... Надеюсь, я отредактирую этот комментарий с рабочим plunkr
 Günter Zöchbauer05 июл. 2016 г., 15:14
Просто добавьте комментарий, когда вы предоставите ссылку на плункер, чтобы я получал уведомления.
 Günter Zöchbauer05 июл. 2016 г., 14:40
Вы импортировалиAuthGuard вmaster.routes.ts а такжеlogin.routes.ts?
 Günter Zöchbauer05 июл. 2016 г., 14:52
У меня нет идей оAuthGuard хоть.
 Günter Zöchbauer05 июл. 2016 г., 14:47
Если вы удалитеcanActivate: [AuthGuard]маршрутизация работает?
 Günter Zöchbauer05 июл. 2016 г., 14:44
Есть лиAuthGuard есть параметры конструктора? Есть ли у него@Injectable() декоратор?
 Alex Beugnet05 июл. 2016 г., 14:56
Спасибо, по крайней мере, я могу очистить предупреждения :-) Ну, где-то должна быть ошибка, потому что все маршруты работают нормально, и я просто следовал руководству до canActivate Milestone ...
 Günter Zöchbauer05 июл. 2016 г., 16:14
Пожалуйста. Рад слышать, что ты понял это.
 Alex Beugnet05 июл. 2016 г., 16:10
Большое спасибо за вашу помощь, Гюнтер, хотя в конце концов это не было чем-то особенным ...
 Günter Zöchbauer05 июл. 2016 г., 14:57
Вы можете попробовать воспроизвести в Plunker, тогда я могу посмотретьangular.io/resources/live-examples/quickstart/ts/plnkr.html
 Günter Zöchbauer05 июл. 2016 г., 14:51
 Günter Zöchbauer05 июл. 2016 г., 16:04
Это может быть проблема с вашей конфигурацией.

Ответы на вопрос(11)

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

Ответ ниже в учебнике. См. Списки файлов в разделе «Добавление компонента LoginComponent» в разделе «Маршрут без компонентов: ...» в «Milestone 5: Route Guards». Он показывает, что 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
  ],
  ...
 wildrhombus22 февр. 2018 г., 04:17
Спасибо за это, я застрял в учебнике, и это очень помогло. Я думал, что они должны быть в appModule, но их нет в окончательной версии кода, и я не мог понять, как это работает без них.

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

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

Импорт обоихHttpModule а такжеHttpClientModule помог мне.

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

У меня возникла такая же проблема после прохождения раздела Route Guards учебника по маршрутизации и авторизации на веб-сайте 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 к провайдерам, не знаю почему.

 Anand Vaidya12 апр. 2019 г., 09:56
Вы спасли мой день!
Решение Вопроса

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

Я печатал

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

вместо

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

сделать это не работает, но в то же время не отображает мне никаких ошибок ...

(грустное лицо)

 Alex Beugnet01 дек. 2016 г., 19:16
Да, я использую VS 2015, но очевидно, что он не так хорош, как Visual Code.
 Abdul Mannan12 окт. 2016 г., 14:44
Вот почему рекомендуется использовать редактор с поддержкой машинописного текста, такой как код Visual Studio (это лучший вариант).
 Mahesh09 мар. 2018 г., 14:27
Я столкнулся с такой же проблемой, наконец нашел, проблема заключается в том, что путь импорта чувствителен к регистру

@Injectable({ providedIn: 'root' }) не нужно добавлять в модуль провайдера.

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

// app.module.ts

 .. 
 providers: [
   AuthGuard,
   UserService,
   ProjectService
  ]

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

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

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

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

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

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

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

 Redplane07 июн. 2017 г., 17:50
Я поместил WhatEverGuard в одинарные кавычки, и он показал, что у меня нет провайдера ... это так раздражало
 Chris Gilbert19 июл. 2017 г., 12:55
Я тоже. У меня было: canActivate: ['AuthGuard', AuthGuard] Как только я удалил литерал, он работал.

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

Ваш ответ на вопрос