Angular拦截器添加JWT请求头后仍返回401未授权问题
问题描述
我用NestJS + Angular实现授权功能,通过Guard保护用户信息接口,仅当请求头携带JWT时才可访问用户详情。用户登录后生成JWT并存储在localStorage中,请求时以Bearer Token形式放在Authorization请求头里。该逻辑在Postman中测试正常,但Angular发起Get请求获取用户详情时返回401未授权错误。
错误信息
user.service.ts:20 ERROR Error: Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":401,"statusText":"Unauthorized","url":"http://localhost:3000/users/byId/63891e7e893aa91d5783fa69","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://localhost:3000/users/byId/63891e7e893aa91d5783fa69: 401 Unauthorized","error":{"statusCode":401,"message":"Unauthorized"}} at resolvePromise (zone.js:1211:31) at zone.js:1118:17 at zone.js:1134:33 at asyncGeneratorStep (asyncToGenerator.js:6:1) at _throw (asyncToGenerator.js:29:1) at _ZoneDelegate.invoke (zone.js:372:26) at Object.onInvoke (core.mjs:26231:33) at _ZoneDelegate.invoke (zone.js:371:52) at Zone.run (zone.js:134:43) at zone.js:1275:36
拦截器代码
intercept( req: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> { let service = this.inject.get(AuthService); const token = localStorage.getItem('accesstoken'); if (token) { console.log('Before', token); const authRequest = this.addTokenHeader(req, token); console.log('After', authRequest); return next.handle(authRequest).pipe( catchError((error: HttpErrorResponse) => { if (error.status === 401) { alert('401 Unathurized'); this.route.navigate(['authentication/login']); } return throwError(error); }) ); } else { return next.handle(req); } }
addTokenHeader函数代码
addTokenHeader(request: HttpRequest<any>, token: string | null) { return request.clone({ headers: request.headers.set('Authorization', 'Bearer' + token!), }); }
问题原因及解决方法
问题出在addTokenHeader函数的Authorization头拼接逻辑——Bearer关键字和token之间缺少一个空格。标准的Bearer Token格式应为Bearer <token>,而当前代码拼接后会变成Bearerxxxxxxxxx(无空格),导致后端Guard无法正确解析JWT,从而返回401未授权。
修改addTokenHeader函数,在Bearer后添加空格即可解决:
addTokenHeader(request: HttpRequest<any>, token: string | null) { return request.clone({ headers: request.headers.set('Authorization', 'Bearer ' + token!), }); }
可在拦截器中添加日志,确认最终请求头格式正确:
console.log('Authorization header:', authRequest.headers.get('Authorization'));
内容的提问来源于stack exchange,提问作者M Nouman
相关产品推荐
相关产品推荐

