Angular 2获取用户信息报错:未提供认证凭证,预检返回401
我尝试通过Angular服务的GET请求获取用户信息,代码如下:
import { Injectable } from '@angular/core'; import {homeUrls} from "../../../utils/urls"; import {Http, RequestOptions, Response} from '@angular/http'; import { Headers } from '@angular/http'; @Injectable() export class AdsService { private headers = new Headers({'Content-Type': 'application/json'}); private token: string; constructor(private http: Http) { this.token = localStorage.getItem('token'); console.log("token is " , this.token); this.headers.set('Authorization', 'Token ' + this.token ); console.log("header is"); console.log(this.headers); this.getMe(); } getMe(): Promise<any> { return this.http.get(homeUrls.User, {headers: this.headers}) .toPromise() .then(res=> { console.log("user is"); console.log(res.json()); }) }
但出现如下错误:
failed to load http://127.0.0.1:8000/users/account/me/: Response for preflight has invalid HTTP status code 401.
在网络面板中显示“authentication credentials were not provided”,尽管我已在服务构造函数中设置了Authorization头,请问问题出在哪里?
这个问题的根源在于跨域预检的OPTIONS请求没带上认证头,后端直接拒绝了这个预检请求,才导致后续的GET请求根本发不出去。
浏览器处理跨域且带自定义请求头(比如你这里的Authorization)的请求时,会先自动发一个OPTIONS预检请求,用来询问后端:“我能不能发这个带自定义头的请求?”。你的代码里虽然给GET请求加了Authorization头,但这个头不会被自动加到OPTIONS请求里,后端在处理OPTIONS请求时没收到认证凭证,就返回了401,直接阻断了后续流程。
给你两个关键的解决方向:
后端调整CORS配置,放行OPTIONS请求和认证头
看你的接口地址像是Django后端,推荐用django-cors-headers库来配置CORS。需要确保:- 把
Authorization加入到允许的请求头列表里 - 允许OPTIONS方法
- 让后端的认证中间件跳过对OPTIONS请求的校验(毕竟预检请求只是确认权限,不需要实际认证)
举个配置示例:
# settings.py CORS_ALLOW_HEADERS = [ 'accept', 'accept-encoding', 'authorization', # 必须加这个 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', ] CORS_ALLOW_METHODS = [ 'DELETE', 'GET', 'OPTIONS', # 允许OPTIONS方法 'PATCH', 'POST', 'PUT', ]另外要注意,如果你用了DRF的认证中间件,得确保它不对OPTIONS请求做校验,比如可以在中间件里判断请求方法,跳过OPTIONS的认证。
- 把
前端确认token的有效性和设置时机
你可以先确认下localStorage.getItem('token')是不是真的拿到了有效token——有时候页面刚加载时,localStorage的读取可能有延迟,或者token已经过期失效了。可以加个判断再调用请求:constructor(private http: Http) { this.token = localStorage.getItem('token'); console.log("token is " , this.token); if (this.token) { this.headers.set('Authorization', 'Token ' + this.token ); console.log("header is", this.headers); this.getMe(); } else { console.error("没从localStorage拿到token哦"); } }
最后可以打开浏览器开发者工具的网络面板,看下OPTIONS请求的详情:如果OPTIONS请求里确实没有Authorization头,那就是后端CORS配置的问题;如果有,但后端还是返回401,那就是后端的认证逻辑没跳过OPTIONS请求的校验。
内容的提问来源于stack exchange,提问作者Shoaib Iqbal

