Angular 1.1.x至1.5.x中Authentication Header无效问题求助
问题根源
你的问题核心出在**跨域预检请求(OPTIONS)**上:浏览器在发送带自定义头(比如Authorization)的跨域POST请求前,会自动触发一个OPTIONS预检请求,这个请求不会携带你设置的Authorization头,但你的Web API在OnValidateClientAuthentication里对所有请求都做了客户端认证校验,包括OPTIONS请求,导致预检直接失败,后续的POST请求根本没机会发送。而Postman不会触发浏览器的预检机制,所以能正常携带Authorization头完成认证。
解决方案
第一步:修改Web API,让OPTIONS请求跳过认证校验
你需要在OnValidateClientAuthentication逻辑最开始,先判断请求方法是否为OPTIONS,如果是则直接通过校验,不执行后续的客户端密钥验证:
OnValidateClientAuthentication = async context => { // 优先处理OPTIONS预检请求,直接通过无需认证 if (context.Request.Method == HttpMethod.Options) { context.Validated(); return; } string clientId; string clientSecret; if (context.TryGetBasicCredentials(out clientId, out clientSecret)) { if (clientId == "client1" && clientSecret == "secretKey1") { context.Validated(); } } }
同时,确保Web API已经启用CORS支持,允许你的Angular应用域名、Authorization头和所需的请求方法:
using System.Web.Http.Cors; public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 替换为你的Angular应用实际域名,允许Authorization头和POST/OPTIONS方法 var corsSettings = new EnableCorsAttribute("http://your-angular-app-domain.com", "*", "*"); config.EnableCors(corsSettings); // 其他路由及API配置... } }
第二步:调整Angular端的请求配置
你之前的两种方式都可行,但需要注意几个细节:
- 不要在请求头里加
Access-Control-Allow-Origin,这是服务端返回的响应头,前端请求加了没用。 - 确保
window.btoa里的clientId和后端校验的client1大小写一致(你之前写的是Client1,大小写不匹配会导致认证失败)。
调整后的服务示例:
app.service('memberService', function ($http) { // 确保clientId和后端完全一致(小写client1) const authHeader = 'Basic ' + window.btoa("client1:secretKey1"); this.GetTocken = function (data) { return $http({ method: "POST", url: window.g_baseUrl + "accesstoken", headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': authHeader }, data: data }); }; });
验证步骤
- 重启Web API服务,确保CORS和OPTIONS处理的代码生效。
- 打开浏览器开发者工具的Network面板,触发Angular的接口调用:
- 先看OPTIONS请求的响应是否为200 OK。
- 再检查后续的POST请求是否携带了Authorization头。
- 如果仍有问题,确认Authorization的Base64编码是否正确,或者后端的clientId/secret是否和前端完全匹配。
内容的提问来源于stack exchange,提问作者Ashwini
相关产品推荐
相关产品推荐

