所以我在我的VS2015解决方案中安装了NuGet包Microsoft.AspNet.WebApi.Cors.5.2.3
,并在我的Web Api项目中启用了CORS。
我已成功使用Fidder测试我的/token
POST请求,以及我对API控制器\api\values
的GET请求。
如果我使用我在Fiddler中收到的令牌,并将其硬编码到我的JavaScript GET请求中 - 我确实可以从我的单页应用程序向\api\values
成功请求。
问题:我无法在本地开发环境中向http://localhost:17883/token
发出成功的POST请求。
Chrome中的错误是:
XMLHttpRequest cannot load http://localhost:17883//token.
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
XHR failed loading: POST "http://localhost:17883//token".
我在WebApiConfig.cs中启用了CORS -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json.Serialization;
namespace API
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
// *** ENABLE CORS ***
var cors = new System.Web.Http.Cors.EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
在我的Angular authService
中,我编写了一个API测试函数,该函数连接到我的Login
页面上的按钮(此请求成功):
var _apitest = function ()
{
var deferred = $q.defer();
var tkn='cbJZpiF-rEdi_WgWzuFOAxPZ0lBiqivEnOmpSYMPu_fuvu37cpLFzHhzc119GfwIc6dnDivYhhH2a1O2bMa6EExRGa3lvPfzZJHiDDaH6klIU2NFEG5FMxFl_-Z_jBQvPkPyW_31iP6P_oVNZZpXzkQfkwA4zilzKLE7If2Dko6MNNID1lscVfkZ4emJXWpalSXCS4A7qmO-ceIchMfrcbZHgVqBjZC_YHz-DxAfg2lTksUdn8NBir_cDOH5Ymsrzj_bKP1H6WJULDfZEPuh0PpB2DlJEXOV63KWUf7Eubp_FYfni5czD1Z-lh2a2RPRfpRxlMQVBUCCp03_Ul5a6lzOFHSJCJlynidw2DV_InK-oFZEuvQK2Xiy_7wq0JVmx-Nej1bQRN7b2eWK25jjdrTfCNyMdtmDZ7qOSmX3dWuyQhCbp_15ciFhmr7wfIYPzsFssbg-XHtDi2lw87KkJ0IhNmtnsoNyKCrM5ibJG5O5t_gxr3l52JN54Jj2mbeY';
var req={
"method": "GET",
"url": "http://localhost:17883/api/values",
"headers": {
"Authorization": "Bearer " + tkn
}
};
$http(req).then(function (data)
{
deferred.resolve(data);
});
return deferred.promise;
};
此\token
的POST请求未成功:
var _loginUserPost = function (loginData)
{
var controllerpath = "/token";
var url = serviceBase + controllerpath;
var body = "username=" + loginData.userName + "&password=" + loginData.password + "&grant_type=password";
var deferred = $q.defer();
deferred.notify("Logging in user...");
// POST REQUEST !!
var req = {
method: 'POST',
encoding: 'JSON',
headers: {
'Content-Type': 'application;x-www-form-urlencoded'
},
url: url,
data: body
};
$http(req).then(function (data)
{
deferred.resolve(data);
}, function (err)
{
deferred.reject("Failed to login user via api call.");
console.log("Failed to login user via api call. Errors details: " + err);
});
return deferred.promise;
}
我还尝试使用ApplicationOAuthProvide
属性修饰EnableCors
类,但它仍然不起作用:
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
...
}
我真的需要知道我错过了什么。我一直在寻找和尝试不同的东西 - 但无济于事。
建议表示赞赏。
鲍勃
*********更新 - 到目前为止我尝试了什么************
但是,\token
的请求在Chrome中以CORS例外被踢回。
我尝试添加Headers
失败(在本文中搜索“第10步:”http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/):
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); // BM:
...
}
答案 0 :(得分:1)
确保控制器中有Options()Action。它可能在帖子之前发出预检选项请求而没有找到匹配的动作。
public HttpResponseMessage Options()
{
return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
}
根据IIS的配置方式,您可能还需要在web.config中允许选项请求
<system.webServer>
<security>
<requestFiltering>
<verbs applyToWebDAV="false">
<add verb="OPTIONS" allowed="true" />
</verbs>
</requestFiltering>
</security>
<system.webServer>
另外,请确保您在Angular中指定的内容类型与Web Api所期望的内容类型相同
var req = {
// ...
headers:
'Content-Type': 'application;x-www-form-urlencoded'
},
// ..
};