Ionic 4、Angular 8 和 HTTP 拦截器
Ionic 4, Angular 8 and HTTP interceptor
我正在使用 Ionic 4 和 Angular 8 构建移动应用程序,但无法使我的 HTTP 拦截器工作。
我在这里查看了所有拦截器示例,但 none 符合我的需要或者根本不再工作。
与常规 Angular 8 版本的唯一区别是从存储中读取令牌的第一行。原始 Angular 8 代码同步读取此类内容,不需要订阅,因此可以正常工作。这个是Ionic storage,它以异步方式调用本地资源。
这是我的代码:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
from(this.storage.get('id_token')).subscribe(res => {
const idToken = res;
if (idToken) {
const cloned = req.clone({ headers: req.headers.set('token', idToken)});
return next.handle(cloned);
} else {
console.log('Unauthorized calls are redirected to login page');
return next.handle(req).pipe(
tap(
event => {
// logging the http response to browser's console in case of a success
if (event instanceof HttpResponse) {
// console.log('api call success :', event);
}
},
error => {
// logging the http response to browser's console in case of a failure
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
this.router.navigateByUrl('/');
}
}
}
)
);
}
});
}
以这种形式编译,但我的 IDE 报告:TS2355(函数必须 return 一个值)。
这里有什么问题或缺失?我想不通。
好的,看起来你正试图在 1 个拦截器中做两件事:
- 添加 Bearer 令牌
- 如果错误代码为 401 - 重定向到主页
此外,您将在每次请求时访问存储,这非常昂贵。
这是我所做的:
- 创建身份验证服务并在那里管理令牌
- 在 auth 服务中有一个 BehaviourSubject 存储令牌的最后一个值
这里是:
// JWT interceptor
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthenticationService } from '../services/authentication.service';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
const currentAuthToken = this.authenticationService.currentAuthTokenValue;
if (currentAuthToken && currentAuthToken.token) {
const headers = {
'Authorization': `Bearer ${currentAuthToken.token}`,
};
if (request.responseType === 'json') {
headers['Content-Type'] = 'application/json';
}
request = request.clone({
setHeaders: headers
});
}
return next.handle(request);
}
}
authenticationService.currentAuthTokenValue 只是 getter returns 当前主题的值
public get currentAuthTokenValue(): AuthToken {
return this.currentAuthTokenSubject.value;
}
还有另一个错误拦截器:
// Error interceptor
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { AuthenticationService } from '../services/authentication.service';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(err => {
if (err.status === 401) {
// auto logout if 401 response returned from api
this.authenticationService.logout().then(() => {
location.reload();
});
}
const error = err.error.message || err.error.detail || err.statusText;
return throwError(error);
}));
}
}
希望对您有所帮助。
我正在使用 Ionic 4 和 Angular 8 构建移动应用程序,但无法使我的 HTTP 拦截器工作。 我在这里查看了所有拦截器示例,但 none 符合我的需要或者根本不再工作。
与常规 Angular 8 版本的唯一区别是从存储中读取令牌的第一行。原始 Angular 8 代码同步读取此类内容,不需要订阅,因此可以正常工作。这个是Ionic storage,它以异步方式调用本地资源。
这是我的代码:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
from(this.storage.get('id_token')).subscribe(res => {
const idToken = res;
if (idToken) {
const cloned = req.clone({ headers: req.headers.set('token', idToken)});
return next.handle(cloned);
} else {
console.log('Unauthorized calls are redirected to login page');
return next.handle(req).pipe(
tap(
event => {
// logging the http response to browser's console in case of a success
if (event instanceof HttpResponse) {
// console.log('api call success :', event);
}
},
error => {
// logging the http response to browser's console in case of a failure
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
this.router.navigateByUrl('/');
}
}
}
)
);
}
});
}
以这种形式编译,但我的 IDE 报告:TS2355(函数必须 return 一个值)。 这里有什么问题或缺失?我想不通。
好的,看起来你正试图在 1 个拦截器中做两件事:
- 添加 Bearer 令牌
- 如果错误代码为 401 - 重定向到主页
此外,您将在每次请求时访问存储,这非常昂贵。
这是我所做的:
- 创建身份验证服务并在那里管理令牌
- 在 auth 服务中有一个 BehaviourSubject 存储令牌的最后一个值
这里是:
// JWT interceptor
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthenticationService } from '../services/authentication.service';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
const currentAuthToken = this.authenticationService.currentAuthTokenValue;
if (currentAuthToken && currentAuthToken.token) {
const headers = {
'Authorization': `Bearer ${currentAuthToken.token}`,
};
if (request.responseType === 'json') {
headers['Content-Type'] = 'application/json';
}
request = request.clone({
setHeaders: headers
});
}
return next.handle(request);
}
}
authenticationService.currentAuthTokenValue 只是 getter returns 当前主题的值
public get currentAuthTokenValue(): AuthToken {
return this.currentAuthTokenSubject.value;
}
还有另一个错误拦截器:
// Error interceptor
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { AuthenticationService } from '../services/authentication.service';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(err => {
if (err.status === 401) {
// auto logout if 401 response returned from api
this.authenticationService.logout().then(() => {
location.reload();
});
}
const error = err.error.message || err.error.detail || err.statusText;
return throwError(error);
}));
}
}
希望对您有所帮助。