NullInjectorError: нет поставщика для JwtHelperService

Я в Angular 5.

Первый: npm install @auth0/angular-jwt --save

Потом импортирую: import { JwtHelperService } from '@auth0/angular-jwt';

Это моя служба аутентификации:

import { JwtHelperService } from '@auth0/angular-jwt';

@Injectable()
export class AuthService {

  constructor(public jwtHelper: JwtHelperService) { }

  public isAuthenticated(): boolean {
    console.info (localStorage['token']);
    const token = localStorage.getItem('token');
    // Check wheter the token is expired and return true or false
    return !this.jwtHelper.isTokenExpired(token);
  }
}

А это моя служба охраны

export class GuardService implements CanActivate {

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

  canActivate(): boolean {
    if (!this.auth.isAuthenticated()){
        console.info ('bye');
        this.router.navigate(['/login']);
        return false;
    }
    console.info ('Welcome');
    return true;
  }

}

В локальном хранилище есть токен:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFjMTUyNzZhZjA2MjU1YTdlMDM0MmQ5ODg4N2M1ZmI2ZWNmM2RlNGUyNjhmYTc4MTliODRhOTVmMmJiNGZiMTliMDFkNjBhNWRlNjhlN2VlIn0.eyJhdWQiOiJmMDExY2M1OC00MGNlLTQzYTktOGY3MS04NDI0OTRlM2E5OTciLCJqdGkiOiJhYzE1Mjc2YWYwNjI1NWE3ZTAzNDJkOTg4ODdjNWZiNmVjZjNkZTRlMjY4ZmE3ODE5Yjg0YTk1ZjJiYjRmYjE5YjAxZDYwYTVkZTY4ZTdlZSIsImlhdCI6MTUyMzI5NzkzNSwibmJmIjoxNTIzMjk3OTM1LCJleHAiOjE1MjMyOTgyMzUsInN1YiI6IjIiLCJzY29wZXMiOlsiYXV0aGVudGljYXRlZCIsImFuZ3VkcnUiXX0.RNY2Yb9xiJDcER4rtHEAYMmoLyvPYij-upZc97q-mSgICKE6_xWih_IBjY4cHQXkkiRyCXaqCfwfMM4YWVjv7bsMlLN5bWlH0JTeYoYf2gENLBIG51NwGpU3iAl8KG_51ljZKbs3RE_ULDbphM1NG8BhobVQ5RlObWzejrkPcMHqlGJaMOMLQuXC1iBR2jI9tlfiP4RD4FUUsRkUEUJ5PSIRl34jWoTv31SSf1bkv43q3YeKTfk6pXZ5Ft_eV8G871KkmQSHANAn26A5ujj2FOh-uCV_VNJ97RuTQ6J4NP2YB-mMaWYpZ1xF-4ndqafRGFXJ_8euBO4cA36zvP3B7g

И это ошибка:

ERROR Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[AuthService -> JwtHelperService]: 
  StaticInjectorError(Platform: core)[AuthService -> JwtHelperService]: 
    NullInjectorError: No provider for JwtHelperService!
Error: StaticInjectorError(AppModule)[AuthService -> JwtHelperService]: 
  StaticInjectorError(Platform: core)[AuthService -> JwtHelperService]: 
    NullInjectorError: No provider for JwtHelperService!
    at _NullInjector.get (core.js:1002)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.get (core.js:1110)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.get (core.js:1110)
    at resolveNgModuleDep (core.js:10854)
    at _createClass (core.js:10891)
    at _createProviderInstance$1 (core.js:10865)
    at _NullInjector.get (core.js:1002)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.get (core.js:1110)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.get (core.js:1110)
    at resolveNgModuleDep (core.js:10854)
    at _createClass (core.js:10891)
    at _createProviderInstance$1 (core.js:10865)
    at resolvePromise (zone.js:814)
    at resolvePromise (zone.js:771)
    at eval (zone.js:873)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4740)
    at ZoneDelegate.invokeTask (zone.js:420)
    at Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)

Кроме того, он показывает мне маршрут, но без массива из службы ...

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
25
0
19 540
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Ответ принят как подходящий

Вам нужно использовать JwtModule, предоставляемый @auth0/angular-jwt, который добавит JwtHelperService к поставщикам, или вам нужно добавить его вручную к поставщику модулей.

Что-то вроде

const JWT_Module_Options: JwtModuleOptions = {
    config: {
        tokenGetter: yourTokenGetter,
        whitelistedDomains: yourWhitelistedDomains
    }
};

@NgModule({
    imports: [
        JwtModule.forRoot(JWT_Module_Options)
    ],
...

Подробнее см. Документация

Да, желательно использовать в верхнем модуле

Suren Srapyan 09.04.2018 20:27

Для справки в будущем, если все, для чего вы хотите использовать JwtHelper, - это декодирование, как в этом случае, проверяя, истек ли срок действия токена, вы можете использовать это.

import { JwtHelperService } from '@auth0/angular-jwt';

const jwtHelper = new JwtHelperService();

@Injectable()
export class AuthService {
    public isAuthenticated(): boolean {
    const token = localStorage.getItem('token');

    // Check if the token is expired and return true or false
    return !this.jwtHelper.isTokenExpired(token);
}

Источник: Документация

Немного поздно для вечеринки, но я столкнулся с той же проблемой, пытаясь следовать автономной документации, и то, что она не охватывает, - это необходимость импорта параметров InjectionToken, на которые есть ссылка в конструкторе службы:

import { JwtHelperService, JWT_OPTIONS  } from '@auth0/angular-jwt';

...

providers: [
        { provide: JWT_OPTIONS, useValue: JWT_OPTIONS },
        JwtHelperService
    ]

они идут в app.module.ts?

Hemang 28.04.2020 06:21

Думаю, это должен быть правильный ответ.

Don Dilanga 01.12.2020 20:22

Я исправил эту проблему, изменив свой импорт из:

import { JwtHelperService } from '@auth0/angular-jwt';

к

import { JwtHelperService } from '@auth0/angular-jwt/src/jwthelper.service';

Это нестандартная и поэтому не рекомендуемая практика.

rguerin 27.11.2019 17:19

Самым простым решением, которое сработало для меня, является объявление типа постоянной переменной «JwtHelperService» вместо объявления ее в конструкторе.

 const helper = new JwtHelperService ();

Теперь используйте вспомогательные сервисы с вспомогательной константой

 return !helper.isTokenExpired(token);

Эта проблема возникает из-за того, что вы не добавили JWTmodule для импорта в app.module.ts

export function tokenGetter() {
  return localStorage.getItem("access_token");
}

JwtModule.forRoot({
      config: {
        tokenGetter: tokenGetter,
        allowedDomains: ["example.com"],
        disallowedRoutes: ["http://example.com/examplebadroute/"],
      },
    }),

Если вы использовали @ auth0 / угловой-jwt для получения помощи jwt и использовали инъекцию зависимостей для доступа к модулю, необходимо импортировать модуль jwt в app.module.ts или какой-либо другой модуль, который вы использовали. Кроме того, у вас есть больше прав для настройки импортеров модулей с запрещенные домены, разрешенные домены, имя заголовка, настраиваемые заводские функции и т. д.

import { JwtModule } from "@auth0/angular-jwt";
import { HttpClientModule } from "@angular/common/http";

export function tokenGetter() {
  return localStorage.getItem("access_token");
}

@NgModule({
  bootstrap: [AppComponent],
  imports: [
    // ...
    HttpClientModule,
    JwtModule.forRoot({
      config: {
       tokenGetter: tokenGetter,
      allowedDomains: ["localhost:3001", "foo.com", "bar.com"]
      },
    }),
  ],
})
export class AppModule {}

если вы не хотите вводить его, вы можете создать экземпляр.

import { JwtHelperService } from "@auth0/angular-jwt";

const helper = new JwtHelperService();

const decodedToken = helper.decodeToken(myRawToken);
const expirationDate = helper.getTokenExpirationDate(myRawToken);
const isExpired = helper.isTokenExpired(myRawToken); 

Я тоже боролся с этой проблемой. Я нашел обходной путь:

Конфигурация теста

В вашем modulename.spec.ts убедитесь, что вы настроили провайдера для JwtHelperService (в моем случае это был AuthGuard.spec.ts):


import { TestBed, inject, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from "@angular/router/testing";
import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing';
import { JwtModule, JwtHelperService } from '@auth0/angular-jwt';

import { AuthGuard } from './auth.guard';

let jwtHelper: JwtHelperService;
const testBedConfiguration = {
  imports: [
    RouterTestingModule.withRoutes([]),
    HttpClientTestingModule,
    JwtModule.forRoot({ // for JwtHelperService
      config: {
        tokenGetter: () => {
          return '';
        }
      }
    })
  ],
  providers: [
    AuthGuard,
    JwtHelperService
  ]
}

describe('AuthGuard', () => {
  beforeEach(() => {
    TestBed.configureTestingModule(testBedConfiguration);
    jwtHelper = TestBed.get(JwtHelperService);
  });

  it('should ...', inject([AuthGuard], (guard: AuthGuard) => {
    expect(guard).toBeTruthy();
  }));
});

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

Другие вопросы по теме