在发送 GET 或 POST 请求之前获取访问令牌
get Access Token before sending GET or POST request
我正在尝试访问构造函数中的令牌,如下面的 utils.service.ts 文件:
utils.service.ts > 构造函数
storage.get('token').then((val) => {
this.token = val;
console.log("token: ", val);
});
我的所有 api get 和 post 请求都需要令牌。当我拨打如下电话时:
utils.service.ts
getDashboard() {
if (this.dashboard) {
return Promise.resolve(this.dashboard);
}
return new Promise(resolve => {
this.http
.get(globals.base_prod_api_url + "dashboard", {
headers: {
"Content-Type": globals.content_type,
Authorization: "Bearer " + this.token
}
})
.subscribe(
data => {
this.dashboard = data;
resolve(this.dashboard);
},
error => {
console.log(error);
this.dashboard = error;
return this.dashboard;
}
);
});
}
dashboard.page.ts
this.utilService.getDashboard().then(data => {
this.dashboard_data = data;
});
甚至在从存储中检索令牌值之前就执行了获取请求。
如何才能先获取令牌然后再向服务器发出获取请求?
我认为你应该使用拦截器来做到这一点。
首先,您必须将其添加到您的 app.module.ts 提供商中:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HttpTokenInterceptor,
multi: true
},
...
],
然后拦截请求并将您的令牌添加到 headers :
import { Injectable, Inject } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http';
import { JwtService } from '../services/jwt.service';
@Injectable({
providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor {
constructor(
private jwtService: JwtService,
) {}
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headersConfig = {
'Accept': 'application/json',
};
storage.get('token').then((token) => {
headersConfig['Authorization'] = `Bearer ${token}`;
return next.handle(request.clone({
setHeaders: headersConfig
}));
});
}
更进一步,您可以使用拦截器来捕获错误:(例如 401 来处理刷新令牌)
return next
.handle(request.clone({
setHeaders: headersConfig
}))
.pipe(
catchError(err => {
if (err.status === 401) {
// token is no longer available, refresh it
}
return throwError(err);
})
);
您可以在 utils.service.ts 中创建私有异步方法
如果令牌的值未定义并且 return 它会 git 令牌。
例如:
async getToken(): Promise<string> {
if(!this.token){
this.token = await storage.get('token');
}
return this.token;
}
并将其他方法标记为异步和 'await' headers object 中的令牌。
例如
async getData(){
....
headers: {
"Content-Type": '...',
Authorization: "Bearer " + await this.getToken()
}
....
}
如果我是你,我会使用 Observables 而不是 Promises。类似于 RXJS 6
import { from } from 'rxjs';
get authToken(): Observable<string> {
return from(storage.get('token')))
}
sendRequest():Observable<ReturnedObject> {
this.authToken.pipe(switchMap(token => {
return this.http
.get(globals.base_prod_api_url + "dashboard", {
headers: {
"Content-Type": globals.content_type,
Authorization: "Bearer " + token
}
})
}))
}
或者 ES6 Promises 装饰器:Async、Await 将从根本上简化您的代码。只是不记得通过 try/catch 块
捕获被拒绝的承诺
我正在尝试访问构造函数中的令牌,如下面的 utils.service.ts 文件:
utils.service.ts > 构造函数
storage.get('token').then((val) => {
this.token = val;
console.log("token: ", val);
});
我的所有 api get 和 post 请求都需要令牌。当我拨打如下电话时:
utils.service.ts
getDashboard() {
if (this.dashboard) {
return Promise.resolve(this.dashboard);
}
return new Promise(resolve => {
this.http
.get(globals.base_prod_api_url + "dashboard", {
headers: {
"Content-Type": globals.content_type,
Authorization: "Bearer " + this.token
}
})
.subscribe(
data => {
this.dashboard = data;
resolve(this.dashboard);
},
error => {
console.log(error);
this.dashboard = error;
return this.dashboard;
}
);
});
}
dashboard.page.ts
this.utilService.getDashboard().then(data => {
this.dashboard_data = data;
});
甚至在从存储中检索令牌值之前就执行了获取请求。 如何才能先获取令牌然后再向服务器发出获取请求?
我认为你应该使用拦截器来做到这一点。
首先,您必须将其添加到您的 app.module.ts 提供商中:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HttpTokenInterceptor,
multi: true
},
...
],
然后拦截请求并将您的令牌添加到 headers :
import { Injectable, Inject } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http';
import { JwtService } from '../services/jwt.service';
@Injectable({
providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor {
constructor(
private jwtService: JwtService,
) {}
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headersConfig = {
'Accept': 'application/json',
};
storage.get('token').then((token) => {
headersConfig['Authorization'] = `Bearer ${token}`;
return next.handle(request.clone({
setHeaders: headersConfig
}));
});
}
更进一步,您可以使用拦截器来捕获错误:(例如 401 来处理刷新令牌)
return next
.handle(request.clone({
setHeaders: headersConfig
}))
.pipe(
catchError(err => {
if (err.status === 401) {
// token is no longer available, refresh it
}
return throwError(err);
})
);
您可以在 utils.service.ts 中创建私有异步方法 如果令牌的值未定义并且 return 它会 git 令牌。 例如:
async getToken(): Promise<string> {
if(!this.token){
this.token = await storage.get('token');
}
return this.token;
}
并将其他方法标记为异步和 'await' headers object 中的令牌。
例如
async getData(){
....
headers: {
"Content-Type": '...',
Authorization: "Bearer " + await this.getToken()
}
....
}
如果我是你,我会使用 Observables 而不是 Promises。类似于 RXJS 6
import { from } from 'rxjs';
get authToken(): Observable<string> {
return from(storage.get('token')))
}
sendRequest():Observable<ReturnedObject> {
this.authToken.pipe(switchMap(token => {
return this.http
.get(globals.base_prod_api_url + "dashboard", {
headers: {
"Content-Type": globals.content_type,
Authorization: "Bearer " + token
}
})
}))
}
或者 ES6 Promises 装饰器:Async、Await 将从根本上简化您的代码。只是不记得通过 try/catch 块
捕获被拒绝的承诺