NullInjectorError: No provider for JwtHelperService
NullInjectorError: No provider for 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.log (localStorage['token']);
const token = localStorage.getItem('token');
// Check wheter the token is expired and return true or false
return !this.jwtHelper.isTokenExpired(token);
}
}
这是我的 Guard 服务
export class GuardService implements CanActivate {
constructor(public auth: AuthService, public router: Router) {}
canActivate(): boolean {
if (!this.auth.isAuthenticated()){
console.log ('bye');
this.router.navigate(['/login']);
return false;
}
console.log ('Welcome');
return true;
}
}
localstorage中有token:
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 (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 (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)
此外,它向我显示了路线,但没有来自服务的数组...
您需要使用@auth0/angular-jwt
提供的JwtModule
,它将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
]
我通过更改我的导入解决了这个问题:
import { JwtHelperService } from '@auth0/angular-jwt';
至
import { JwtHelperService } from '@auth0/angular-jwt/src/jwthelper.service';
对我有用的最简单的解决方案是声明“JwtHelperService”的常量变量类型,而不是在构造函数中声明它。
const helper = new JwtHelperService ();
现在使用带有助手常量的助手服务
return !helper.isTokenExpired(token);
出现这个问题是因为您没有在 app.module.ts
的导入中添加 JWT 模块
export function tokenGetter() {
return localStorage.getItem("access_token");
}
JwtModule.forRoot({
config: {
tokenGetter: tokenGetter,
allowedDomains: ["example.com"],
disallowedRoutes: ["http://example.com/examplebadroute/"],
},
}),
如果您使用 @auth0/angular-jwt 获取 jwt 帮助并使用依赖注入访问模块,则有必要将 jwt 模块导入 app.module.ts 或者你的模块是什么 used.moreover 你有更多的权限来配置你的模块导入器,包括不允许的域、允许的域、header 名称、自定义工厂函数等
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 用于路由的 auth 服务中,我必须在我受 authguard 保护的每个页面中包含该配置。
import { JwtModule, JwtHelperService } from '@auth0/angular-jwt';
public jwtHelper: JwtHelperService = new JwtHelperService();
constructor(
private http: Http,
) { }
decodeToken() {
const token = localStorage.getItem('token');
return this.jwtHelper.decodeToken(token);
}
这解决了我的问题
https://github.com/auth0/angular2-jwt/issues/482#issuecomment-569251938
我在 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.log (localStorage['token']);
const token = localStorage.getItem('token');
// Check wheter the token is expired and return true or false
return !this.jwtHelper.isTokenExpired(token);
}
}
这是我的 Guard 服务
export class GuardService implements CanActivate {
constructor(public auth: AuthService, public router: Router) {}
canActivate(): boolean {
if (!this.auth.isAuthenticated()){
console.log ('bye');
this.router.navigate(['/login']);
return false;
}
console.log ('Welcome');
return true;
}
}
localstorage中有token:
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 (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 (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)
此外,它向我显示了路线,但没有来自服务的数组...
您需要使用@auth0/angular-jwt
提供的JwtModule
,它将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
]
我通过更改我的导入解决了这个问题:
import { JwtHelperService } from '@auth0/angular-jwt';
至
import { JwtHelperService } from '@auth0/angular-jwt/src/jwthelper.service';
对我有用的最简单的解决方案是声明“JwtHelperService”的常量变量类型,而不是在构造函数中声明它。
const helper = new JwtHelperService ();
现在使用带有助手常量的助手服务
return !helper.isTokenExpired(token);
出现这个问题是因为您没有在 app.module.ts
的导入中添加 JWT 模块export function tokenGetter() {
return localStorage.getItem("access_token");
}
JwtModule.forRoot({
config: {
tokenGetter: tokenGetter,
allowedDomains: ["example.com"],
disallowedRoutes: ["http://example.com/examplebadroute/"],
},
}),
如果您使用 @auth0/angular-jwt 获取 jwt 帮助并使用依赖注入访问模块,则有必要将 jwt 模块导入 app.module.ts 或者你的模块是什么 used.moreover 你有更多的权限来配置你的模块导入器,包括不允许的域、允许的域、header 名称、自定义工厂函数等
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 用于路由的 auth 服务中,我必须在我受 authguard 保护的每个页面中包含该配置。
import { JwtModule, JwtHelperService } from '@auth0/angular-jwt';
public jwtHelper: JwtHelperService = new JwtHelperService();
constructor(
private http: Http,
) { }
decodeToken() {
const token = localStorage.getItem('token');
return this.jwtHelper.decodeToken(token);
}
这解决了我的问题 https://github.com/auth0/angular2-jwt/issues/482#issuecomment-569251938