Я в 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)
Кроме того, он показывает мне маршрут, но без массива из службы ...

Вам нужно использовать JwtModule, предоставляемый @auth0/angular-jwt, который добавит JwtHelperService к поставщикам, или вам нужно добавить его вручную к поставщику модулей.
Что-то вроде
const JWT_Module_Options: JwtModuleOptions = {
config: {
tokenGetter: yourTokenGetter,
whitelistedDomains: yourWhitelistedDomains
}
};
@NgModule({
imports: [
JwtModule.forRoot(JWT_Module_Options)
],
...
Для справки в будущем, если все, для чего вы хотите использовать 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?
Думаю, это должен быть правильный ответ.
Я исправил эту проблему, изменив свой импорт из:
import { JwtHelperService } from '@auth0/angular-jwt';
к
import { JwtHelperService } from '@auth0/angular-jwt/src/jwthelper.service';
Это нестандартная и поэтому не рекомендуемая практика.
Самым простым решением, которое сработало для меня, является объявление типа постоянной переменной «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.
Да, желательно использовать в верхнем модуле