配置 NbAuthJWTInterceptor 以适当格式化 JWT 令牌的问题
Problem with configuring NbAuthJWTInterceptor to format JWT tokens appropriately
我正在为我的新应用程序使用 ngx-admin。我已经利用 Nebular Auth 框架来使用 JWT 令牌来启用对 back-end REST 服务器的访问。
在使用 Postman 测试 API 时,我可以通过使用 JWT <token>
格式的令牌格式化授权 HTTP header 来成功验证和访问 REST 服务器。从我基于 ngx-admin 的应用程序访问 API 的问题是 NbAuthJWTInterceptor
class 以 Bearer JWT <token>
格式呈现授权 HTTP header因此我的 back-end API 无法提取令牌。
如何配置或覆盖 NbAuthJWTInterceptor
class 以设置格式为 JWT <token>
的授权 HTTP header?
在客户端我使用:
- ngx-admin 3.2.1
- angular 7.2.1
- nebular/auth 3.4.2
在服务器端,我将以下内容与 MongoDB 一起使用:
- 快递4.6.13
- 护照 0.4.0
- passport-jwt 4.0.0
- jsonwebtoken 8.5.1
- 猫鼬 5.1.7
我已经使用令牌测试了对我的 API 的各种调用(GET、POST、PUT、DELETE) 我已经使用 Postman 成功登录并将授权令牌格式化为 JWT <token>
并且请求被授权并返回了正确的数据。
当我的应用程序提出相同的请求时,NbAuthJWTInterceptor
class 将授权令牌格式化为 Bearer JWT <token>
,因此请求被拒绝为 "Unauthorised"
在 REST 服务器端访问和解码授权令牌:
module.exports = function (passport) {
var opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('JWT');
opts.secretOrKey = config.secret;
passport.use(new JwtStrategy(opts, function (jwt_payload, done) {
User.findOne({
id: jwt_payload._id
}, function (err, user) {
if (err) {
return done(err, false);
}
if (user) {
done(null, user);
} else {
done(null, false);
}
});
}));
};
配置 API 端点和 HTTP 拦截器以在客户端注入授权令牌:
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
AppRoutingModule,
// NbEvaIconsModule,
NgbModule.forRoot(),
ThemeModule.forRoot(),
CoreModule.forRoot(),
NbAuthModule.forRoot({
strategies: [
NbPasswordAuthStrategy.setup({
name: 'email',
token: {
class: NbAuthJWTToken,
key: 'token',
},
baseEndpoint: '/api',
login: {
endpoint: '/auth/signin',
method: 'post',
},
register: {
endpoint: '/auth/signup',
method: 'post',
},
logout: {
endpoint: '/auth/sign-out',
method: 'post',
},
requestPass: {
endpoint: '/auth/request-pass',
method: 'post',
},
resetPass: {
endpoint: '/auth/reset-pass',
method: 'post',
},
}),
],
forms: {
login: formDelaySetting,
register: formDelaySetting,
requestPassword: formSetting,
resetPassword: formSetting,
logout: {
redirectDelay: 0,
},
},
}),
NbThemeModule.forRoot({ name: 'corporate' }),
NbToastrModule.forRoot(),
NbLayoutModule,
],
bootstrap: [AppComponent],
providers: [
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: HTTP_INTERCEPTORS, useClass: NbAuthJWTInterceptor, multi: true },
{ provide: NB_AUTH_TOKEN_INTERCEPTOR_FILTER, useValue: (req) => { return false; } },
],
})
我最终挖掘了所有 @Nebular/auth
模块代码并最终找到了罪魁祸首。 NbAuthJWTInterceptor
具有网络令牌 hard-coded 的 'Bearer ' 部分。所以我不得不克隆 class 并制作然后使用我自己的 HTTP 拦截器:
import { Inject, Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { NbAuthToken } from '@nebular/auth';
import { NbAuthService } from '@nebular/auth';
import { NB_AUTH_TOKEN_INTERCEPTOR_FILTER } from '@nebular/auth';
@Injectable()
export class NgxAuthJWTInterceptor implements HttpInterceptor {
constructor(private injector: Injector,
@Inject(NB_AUTH_TOKEN_INTERCEPTOR_FILTER) protected filter) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// do not intercept request whose urls are filtered by the injected filter
if (!this.filter(req)) {
return this.authService.isAuthenticatedOrRefresh()
.pipe(
switchMap(authenticated => {
if (authenticated) {
return this.authService.getToken().pipe(
switchMap((token: NbAuthToken) => {
//const JWT = `Bearer ${token.getValue()}`; <--- replace this line with the next
const JWT = `${token.getValue()}`;
req = req.clone({
setHeaders: {
Authorization: JWT,
},
});
return next.handle(req);
}),
)
} else {
// Request is sent to server without authentication so that the client code
// receives the 401/403 error and can act as desired ('session expired', redirect to login, aso)
return next.handle(req);
}
}),
)
} else {
return next.handle(req);
}
}
protected get authService(): NbAuthService {
return this.injector.get(NbAuthService);
}
}
我正在使用 nebular/auth 4.2.1 并且仍然有同样的问题,检查代码出现了一些文件夹:esm2015 和 esm5 有一些调用但不清楚,在服务中只有这个:
export declare class NbAuthJWTInterceptor implements HttpInterceptor {
private injector;
protected filter: any;
constructor(injector: Injector, filter: any);
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
protected readonly authService: NbAuthService;
}
我正在为我的新应用程序使用 ngx-admin。我已经利用 Nebular Auth 框架来使用 JWT 令牌来启用对 back-end REST 服务器的访问。
在使用 Postman 测试 API 时,我可以通过使用 JWT <token>
格式的令牌格式化授权 HTTP header 来成功验证和访问 REST 服务器。从我基于 ngx-admin 的应用程序访问 API 的问题是 NbAuthJWTInterceptor
class 以 Bearer JWT <token>
格式呈现授权 HTTP header因此我的 back-end API 无法提取令牌。
如何配置或覆盖 NbAuthJWTInterceptor
class 以设置格式为 JWT <token>
的授权 HTTP header?
在客户端我使用:
- ngx-admin 3.2.1
- angular 7.2.1
- nebular/auth 3.4.2
在服务器端,我将以下内容与 MongoDB 一起使用:
- 快递4.6.13
- 护照 0.4.0
- passport-jwt 4.0.0
- jsonwebtoken 8.5.1
- 猫鼬 5.1.7
我已经使用令牌测试了对我的 API 的各种调用(GET、POST、PUT、DELETE) 我已经使用 Postman 成功登录并将授权令牌格式化为 JWT <token>
并且请求被授权并返回了正确的数据。
当我的应用程序提出相同的请求时,NbAuthJWTInterceptor
class 将授权令牌格式化为 Bearer JWT <token>
,因此请求被拒绝为 "Unauthorised"
在 REST 服务器端访问和解码授权令牌:
module.exports = function (passport) {
var opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('JWT');
opts.secretOrKey = config.secret;
passport.use(new JwtStrategy(opts, function (jwt_payload, done) {
User.findOne({
id: jwt_payload._id
}, function (err, user) {
if (err) {
return done(err, false);
}
if (user) {
done(null, user);
} else {
done(null, false);
}
});
}));
};
配置 API 端点和 HTTP 拦截器以在客户端注入授权令牌:
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
AppRoutingModule,
// NbEvaIconsModule,
NgbModule.forRoot(),
ThemeModule.forRoot(),
CoreModule.forRoot(),
NbAuthModule.forRoot({
strategies: [
NbPasswordAuthStrategy.setup({
name: 'email',
token: {
class: NbAuthJWTToken,
key: 'token',
},
baseEndpoint: '/api',
login: {
endpoint: '/auth/signin',
method: 'post',
},
register: {
endpoint: '/auth/signup',
method: 'post',
},
logout: {
endpoint: '/auth/sign-out',
method: 'post',
},
requestPass: {
endpoint: '/auth/request-pass',
method: 'post',
},
resetPass: {
endpoint: '/auth/reset-pass',
method: 'post',
},
}),
],
forms: {
login: formDelaySetting,
register: formDelaySetting,
requestPassword: formSetting,
resetPassword: formSetting,
logout: {
redirectDelay: 0,
},
},
}),
NbThemeModule.forRoot({ name: 'corporate' }),
NbToastrModule.forRoot(),
NbLayoutModule,
],
bootstrap: [AppComponent],
providers: [
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: HTTP_INTERCEPTORS, useClass: NbAuthJWTInterceptor, multi: true },
{ provide: NB_AUTH_TOKEN_INTERCEPTOR_FILTER, useValue: (req) => { return false; } },
],
})
我最终挖掘了所有 @Nebular/auth
模块代码并最终找到了罪魁祸首。 NbAuthJWTInterceptor
具有网络令牌 hard-coded 的 'Bearer ' 部分。所以我不得不克隆 class 并制作然后使用我自己的 HTTP 拦截器:
import { Inject, Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { NbAuthToken } from '@nebular/auth';
import { NbAuthService } from '@nebular/auth';
import { NB_AUTH_TOKEN_INTERCEPTOR_FILTER } from '@nebular/auth';
@Injectable()
export class NgxAuthJWTInterceptor implements HttpInterceptor {
constructor(private injector: Injector,
@Inject(NB_AUTH_TOKEN_INTERCEPTOR_FILTER) protected filter) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// do not intercept request whose urls are filtered by the injected filter
if (!this.filter(req)) {
return this.authService.isAuthenticatedOrRefresh()
.pipe(
switchMap(authenticated => {
if (authenticated) {
return this.authService.getToken().pipe(
switchMap((token: NbAuthToken) => {
//const JWT = `Bearer ${token.getValue()}`; <--- replace this line with the next
const JWT = `${token.getValue()}`;
req = req.clone({
setHeaders: {
Authorization: JWT,
},
});
return next.handle(req);
}),
)
} else {
// Request is sent to server without authentication so that the client code
// receives the 401/403 error and can act as desired ('session expired', redirect to login, aso)
return next.handle(req);
}
}),
)
} else {
return next.handle(req);
}
}
protected get authService(): NbAuthService {
return this.injector.get(NbAuthService);
}
}
我正在使用 nebular/auth 4.2.1 并且仍然有同样的问题,检查代码出现了一些文件夹:esm2015 和 esm5 有一些调用但不清楚,在服务中只有这个:
export declare class NbAuthJWTInterceptor implements HttpInterceptor {
private injector;
protected filter: any;
constructor(injector: Injector, filter: any);
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
protected readonly authService: NbAuthService;
}