我正在尝试使用 Ionic 4 项目中的 HttpInterceptor 验证对后端的所有 API 调用。令牌通过本机存储保存。当我进行登录调用时出现问题。由于尚无可用令牌,NativeStorage 返回中断链的错误:NativeStorageError {code: 2,来源:"Native",异常:null}
httpConfig.interceptor.ts
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpResponse,
HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError, from } from 'rxjs';
import { map, catchError, switchMap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
import { NativeStorage } from '@ionic-native/native-storage/ngx';
const TOKEN_KEY = 'auth-token';
@Injectable()
export class HttpConfigInterceptor implements HttpInterceptor {
loaderToShow: any;
loadingPresent = false;
debug = false;
constructor(
public loadingController: LoadingController,
private storage: NativeStorage
)
{ }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.storage.getItem(TOKEN_KEY))
.pipe(
switchMap(token => {
if (token) {
request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' + token.access_token) });
}
if (!request.headers.has('Content-Type')) {
request = request.clone({ headers: request.headers.set('Content-Type', 'application/json') });
}
this.showLoader();
return next.handle(request).pipe(
map((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
console.log('event--->>>', event);
}
this.hideLoader();
return event;
}),
catchError((error: HttpErrorResponse) => {
this.hideLoader();
return throwError(error);
})
);
})
);
}
showLoader() {
console.log("show loader");
this.loaderToShow = this.loadingController.create({
message: 'Cargando datos...'
}).then((res) => {
this.loadingPresent = true;
res.present();
res.onDidDismiss().then((dis) => {
console.log('Loading dismissed!');
});
});
}
hideLoader() {
if(this.loadingPresent) {
this.loadingController.dismiss();
this.loadingPresent = false;
}
}
}
auth.service.ts
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Platform } from '@ionic/angular';
import { tap, map } from 'rxjs/operators';
import { NativeStorage } from '@ionic-native/native-storage/ngx';
import { environment } from '../../environments/environment';
import { User } from '../models/user';
import { BehaviorSubject } from 'rxjs';
const TOKEN_KEY = 'auth-token';
@Injectable({
providedIn: 'root'
})
export class AuthService {
isLoggedIn = false;
token:any;
authenticationState = new BehaviorSubject(false);
constructor(
private http: HttpClient,
private storage: NativeStorage,
private plt: Platform
)
{
this.plt.ready().then(() => {
this.checkToken();
});
}
login(login: String, password: String) {
return this.http.post(environment.API_URL + 'auth/login',
{ login: login, password: password }
).pipe(
map(token => {
this.storage.setItem(TOKEN_KEY, token)
.then(
() => {
this.authenticationState.next(true);
},
error => console.error('Error storing item', error)
);
}),
);
}
logout() {
return this.http.get(environment.API_URL + 'auth/logout')
.pipe(
tap(data => {
return this.storage.remove(TOKEN_KEY).then(() => {
this.authenticationState.next(false);
});
})
)
}
isAuthenticated() {
return this.authenticationState.value;
}
checkToken() {
this.storage.getItem(TOKEN_KEY).then(res => {
if (res) {
this.authenticationState.next(true);
}
});
}
}
当我第一次尝试登录时,它会从拦截器返回 NativeStorage 的"找不到令牌"错误 NativeStorageError {code: 2, source: "Native", exception: null}
当项目不存在时,您尝试访问'TOKEN_KEY'
项目。
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.storage.getItem(TOKEN_KEY)) <-- //This causes error
或
checkToken() {
this.storage.getItem(TOKEN_KEY).then(res => { <-- //This causes error
if (res) {
this.authenticationState.next(true);
}
});
}
您必须初始化'TOKEN_KEY'
的默认值或添加 if else 控制(检查)令牌的条件
您可以使用this.storage.keys
列表来查找密钥
其他错误代码:
- NATIVE_WRITE_FAILED = 1
- ITEM_NOT_FOUND = 2
- NULL_REFERENCE = 3
- UNDEFINED_TYPE = 4
- JSON_ERROR = 5
- WRONG_PARAMETER = 6
ionic storage 中的 get 函数将值作为对象返回 { value : "token value "}
所以从存储结果访问值属性,如下所示
request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' +
token.value) });