我在Angular中有一个拦截器,我使用它在令牌过期时刷新令牌,但当令牌成功刷新时,应用程序似乎会陷入对API无止境的401个错误调用中。当我单步执行代码时,令牌确实会在过期时刷新,但随后会尝试重复刷新。
我还应该注意,在再次单击按钮并再次调用API时,应用程序将获得新的令牌,并在随后正常工作。不过,我希望在没有这么多控制台错误的情况下工作。
import { Injectable, Injector } from "@angular/core";
import { Router } from "@angular/router";
import {
HttpClient,
HttpHandler, HttpEvent, HttpInterceptor,
HttpRequest, HttpResponse, HttpErrorResponse
} from "@angular/common/http";
import { AuthService } from "./auth.service";
import { Observable } from "rxjs/Observable";
@Injectable()
export class AuthResponseInterceptor implements HttpInterceptor {
currentRequest: HttpRequest<any>;
auth: AuthService;
constructor(
private injector: Injector,
private router: Router
) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.auth = this.injector.get(AuthService);
var token = (this.auth.isLoggedIn()) ? this.auth.getAuth()!.token : null;
if (token) {
// save current request
this.currentRequest = request;
return next.handle(request)
.do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// do nothing
}
})
.catch(error => {
return this.handleError(error)
});
}
else {
return next.handle(request);
}
}
handleError(err: any) {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
// JWT token might be expired:
// try to get a new one using refresh token
console.log("Token expired. Attempting refresh...");
this.auth.refreshToken()
.subscribe(res => {
if (res) {
// refresh token successful
console.log("refresh token successful");
// re-submit the failed request
var http = this.injector.get(HttpClient);
http.request(this.currentRequest).subscribe(
(result: any) => {
console.log(this.currentRequest);
}, (error: any) => console.error(error)
);
}
else {
// refresh token failed
console.log("refresh token failed");
// erase current token
this.auth.logout();
// redirect to login page
this.router.navigate(["login"]);
}
}, error => console.log(error));
}
}
return Observable.throw(err);
}
}
import { Injectable, Injector } from "@angular/core";
import { Router } from "@angular/router";
import {
HttpClient,
HttpHandler, HttpEvent, HttpInterceptor,
HttpRequest, HttpResponse, HttpErrorResponse, HttpHeaders
} from "@angular/common/http";
import { AuthService } from "./auth.service";
import { Observable, Subject } from "rxjs";
@Injectable()
export class AuthResponseInterceptor implements HttpInterceptor {
auth: AuthService;
currentRequest: HttpRequest<any>;
constructor(
private injector: Injector,
private router: Router
) { }
logout() {
this.auth.logout();
this.router.navigate(["login"]);
}
intercept(
request: HttpRequest<any>,
next: HttpHandler): Observable<HttpEvent<any>> {
this.auth = this.injector.get(AuthService);
let token = (this.auth.isLoggedIn()) ? this.auth.getAuth()!.token : null;
this.currentRequest = request;
return next.handle(request).
catch((error) => {
if (error instanceof HttpErrorResponse && error.status === 401) {
return this.auth.refreshToken()
.switchMap(() => {
let token = (Response) ? this.auth.getAuth() : null;
console.log(token);
if (token) {
this.currentRequest = request.clone({
setHeaders: {
Authorization: `Bearer ${token.token}`
}
});
}
return next.handle(this.currentRequest);
}).
catch((e) => {
this.logout();
console.error(e);
return Observable.empty();
});
}
return Observable.throw(error);
});
}
}
constructor(private http: HttpClient,
@Inject(PLATFORM_ID) private platformId: any) {
}
// performs the login
login(username: string, password: string): Observable<boolean> {
var url = "api/token/auth";
var data = {
username: username,
password: password,
client_id: this.clientId,
// required when signing up with username/password
grant_type: "password",
// space-separated list of scopes for which the token is issued
scope: "offline_access profile email"
};
return this.getAuthFromServer(url, data);
}
// try to refresh token
refreshToken(): Observable<boolean> {
var url = "api/token/auth";
var data = {
client_id: this.clientId,
// required when signing up with username/password
grant_type: "refresh_token",
refresh_token: this.getAuth()!.refresh_token,
// space-separated list of scopes for which the token is issued
scope: "offline_access profile email"
};
return this.getAuthFromServer(url, data);
}
// retrieve the access & refresh tokens from the server
getAuthFromServer(url: string, data: any): Observable<boolean> {
return this.http.post<TokenResponse>(url, data)
.map((res) => {
let token = res && res.token;
// if the token is there, login has been successful
if (token) {
// store username and jwt token
this.setAuth(res);
// successful login
return true;
}
// failed login
return Observable.throw('Unauthorized');
})
.catch(error => {
return new Observable<any>(error);
});
}
// performs the logout
logout(): boolean {
this.setAuth(null);
return true;
}
// Persist auth into localStorage or removes it if a NULL argument is given
setAuth(auth: TokenResponse | null): boolean {
if (isPlatformBrowser(this.platformId)) {
if (auth) {
localStorage.setItem(
this.authKey,
JSON.stringify(auth));
}
else {
localStorage.removeItem(this.authKey);
}
}
return true;
}
// Retrieves the auth JSON object (or NULL if none)
getAuth(): TokenResponse | null {
if (isPlatformBrowser(this.platformId)) {
var i = localStorage.getItem(this.authKey);
if (i) {
return JSON.parse(i);
}
}
return null;
}
// Returns TRUE if the user is logged in, FALSE otherwise.
isLoggedIn(): boolean {
if (isPlatformBrowser(this.platformId)) {
return localStorage.getItem(this.authKey) != null;
}
return false;
}
return this.auth.refreshToken(response:any)
//response can be true or null
let token=(response)?this.auth.getAuth():null;
//In token we have an object of type TokenResponse
console.log(token)
.switchMap(() => {
if (token) {
this.currentRequest = request.clone({
setHeaders: { //I think it's toke.token
Authorization: `Bearer ${token.token}`
}
});
....
注意:尝试将“var”改为“let”注意2:一开始你有
var token = (this.auth.isLoggedIn()) ? this.auth.getAuth()!.token : null;
// May be remove "!"?
let token = (this.auth.isLoggedIn()) ? this.auth.getAuth().token : null;
我需要(在拦截器类中)对403禁止的HTTP状态(获取/刷新)JWT令牌作出反应,并使用新令牌重试请求。 在下面的代码中,当服务器返回错误响应时,它将转到成功回调(而不是像我预期的那样进入错误回调),事件是typeof object(这在错误响应的反应中是无用的)。事件对象如下所示:{type:0}。 问题: -当我需要刷新accessToken并重试http请求时,如何在HttpIntercep
我已经实现了 JWT 和刷新令牌流。当我过去实现这一点时,我的做法略有不同,主要是刷新令牌是在正文中发送的。 但是现在我做了不同的事情,我必须通过授权标头发送访问令牌,但是我的拦截器代码不想切换不记名令牌。如何修复,如果我想刷新,我实际上使用刷新令牌作为不记名令牌,而不是过期的访问令牌? 我还尝试在post请求中将HTTP标头设置为授权承载令牌
我正在从事一个spring boot angular项目,其中用户从angular前端登录到spring boot上的身份验证api,该api返回一个JWT令牌。我还在Angular上设置了一个拦截器,该拦截器为所有请求附加带有JWT令牌的授权头。 我正在寻找一种拦截angualar请求的方法,这样当spring boot在JWT令牌过期后抛出401错误时,Angular前端将尝试使用过期的JWT
我有一个使用express api的react应用程序。我正在尝试在访问令牌过期时刷新令牌。我正在使用axios拦截器来实现这一成就。 它卡在某个地方了。我使用console.log来调试它。从控制台; 发布http://localhost:5000/api/auth/token?null 401(未经授权) 之后什么都没发生。我该怎么办?谢谢你的帮助
本文向大家介绍Vue 拦截器对token过期处理方法,包括了Vue 拦截器对token过期处理方法的使用技巧和注意事项,需要的朋友参考一下 最近在做的一个项目,需要每个http请求下 都要添加token,这样无疑是增加了工作量。而vue 拦截器interceptors正好可以解决我们的需求。 以上这篇Vue 拦截器对token过期处理方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望
我正在构建一个移动应用程序,并且正在使用JWT进行身份验证。 最好的方法似乎是将JWT访问令牌与刷新令牌配对,这样我就可以根据需要频繁地使访问令牌过期。 刷新令牌是什么样子的?是随机字符串吗?那串加密了吗?是另一个JWT吗? 刷新令牌将存储在用户模型的数据库中以便访问,对吗?在这种情况下似乎应该加密 在用户登录后,我是否会将刷新令牌发送回,然后让客户端访问单独的路由来检索访问令牌?
问题内容: 我正在使用AngularJS构建SPA,并与服务(JAVA)通信。 当用户发送其用户名/密码时,服务会同时发送回:Acces令牌和Refresh令牌。我正在尝试处理:如果收到状态为401的响应,请发送回刷新令牌,然后再次发送您的上一个请求。我试图通过包含$ http来做到这一点,但是angular不允许我在此拦截器中包含它。有什么方法可以使用我正在接收的响应参数来重新创建原始请求吗?