刷新令牌实现遇401未授权错误,请求技术协助
后端通过PostMan、curl调用均正常:携带refresh token请求头后,能成功返回可用的accessToken;但前端调用时触发401错误,请求协助排查。
拦截器代码
export const customInterceptor: HttpInterceptorFn = (req, next) => { const excludedRoutes = ['/login']; // 可自定义的路由数组 const shouldExclude = excludedRoutes.some(route => req.url.includes(route)); const authService = inject(AuthService); if (shouldExclude) { return next(req); } const token = authService.getAuthToken(); const cloneRequest = req.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); return next(cloneRequest).pipe( catchError((error) => { if (error.status === 401) { console.log("From the interceptor, here is the error: " + error.status); return authService.refreshToken().pipe( switchMap((res) => { localStorage.setItem('authToken', res.accessToken); console.log("From the interceptor, the new authToken is: " + res.accessToken); const newReq = req.clone({ setHeaders: { Authorization: `Bearer ${res.accessToken}` } }); return next(newReq); }), catchError((refreshErr) => { const finalError = new Error(refreshErr); console.log("Error refreshing the token", finalError); authService.logout(); return throwError(() => new Error('Session expired, please log in again')); }) ); } else { // 处理其他错误(如网络错误) return throwError(() => error); } }) ); };
服务方法代码
refreshToken() { const refreshToken = localStorage.getItem('refreshToken'); console.log("The refreshToken inside the method is: " + refreshToken); if (!refreshToken) { throw new Error('Refresh token missing'); } console.log("Sending refresh token to backend: " + refreshToken); return this._httpClient.post<any>(`${this.baseURL}/refresh`, {}, { headers: { Authorization: `Bearer ${refreshToken}` } }).pipe( catchError((error) => { console.error("Refresh token error:", error); return throwError(() => new Error("Refresh error")); }) ); }
排查方向与解决建议
- 拦截器范围问题:当前拦截器仅排除了
/login,但/refresh请求会被自动带上过期的accessToken,导致后端优先校验无效的accessToken返回401。需将/refresh加入excludedRoutes数组,避免拦截器给该请求添加Authorization头。 - 请求头格式校验:在浏览器Network面板查看实际发送的请求头,对比PostMan的请求头,确认
Authorization: Bearer ${refreshToken}格式是否完全一致,检查token是否存在多余空格、转义字符。 - 跨域配置问题:检查后端CORS配置是否允许前端携带
Authorization请求头,若未配置会导致浏览器自动屏蔽该头,触发401。 - Token存储校验:对比console.log输出的refreshToken值与PostMan中使用的token,确认存储和读取过程中是否存在篡改、编码错误。
- 后端校验逻辑:复制浏览器中的请求为curl命令执行,排查是否存在后端对请求来源、User-Agent等额外校验导致的差异。
内容的提问来源于stack exchange,提问作者Gustavo Starace
相关产品推荐
相关产品推荐

