ASP.NET Web Api 获取令牌跨源时遇到问题
ASP.NET Web Api trouble with getting token cross-origin
我在使用跨源内容从我的前端(Node.js 和 Ajax)登录我的 Web Api 时遇到了一些问题。我收到以下错误:
XMLHttpRequest cannot load http://localhost:61102/Token. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 500.
这个问题只有在调用/Token登录的时候才会出现,我可以访问其他路由,完美注册。这是我的代码:
Startup.cs:
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
ConfigureAuth(app);
WebApiConfig.Register(config);
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(config);
}
Startup.Auth.cs:
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
}
并且我在 ApplicationOAuthProvider.cs
中将 context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
放入 GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
我已经尝试寻找答案很长时间了,并且偶然发现了很多不同的答案,但这些答案对我来说都不起作用。不知道怎么了。
更新 - 添加了我的 ajax 脚本
import {URL} from '../constants/AuthConstants';
import request from 'reqwest';
import history from './HistoryService';
let router = null;
class AuthService {
login(email, password) {
console.log(URL.LOGIN);
var grant_type = 'password';
return request({
url: URL.LOGIN,
method: 'POST',
crossOrigin: true,
content-Type
data: {
grant_type, email, password
},
success: function(response) {
console.log("Yay! Login", response);
},
error: function(response) {
console.log("Error! Login", response);
}
});
}
}
您对 CORS 的使用与我过去使用的有所不同。我已经相对成功地完成了以下多次。
在您的 WebApi 项目中添加对 System.Web.Cors
的引用,并将以下内容添加到 WebApiConfig.cs
文件中的 Register
方法:
public static void Register(HttpConfiguration config)
{
config.SetCorsPolicyProviderFactory(new CorsPolicyFactory());
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
可以在此处找到更深入的教程:
http://tostring.it/2014/03/04/how-to-use-CORS-with-ASPNET-WebAPI-2/
天哪,我让它工作了。虽然不确定它是否好或正确的方法(可能不是,但它有效)。我所做的是愤怒地删除了代码中的 app.UseCors(CorsOptions.AllowAll);
和所有其他启用 cors 的东西,并将其添加到 <system.webServer>
:
中的 web.config
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:8080"/>
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
</customHeaders>
</httpProtocol>
我会将其标记为答案,因为它有效,但由于我不确定它是否是解决此问题的正确方法,请告诉我是否正确,我将更改 "correct answer" 内容。
编辑 - 正确的方法
使用上面的方法我可以注册和登录,但无法执行其他调用,例如 "api/values/1"(因为它在发送 [=36= 之前发送了 'OPTIONS' ] 之类的,我不想为其创建处理程序)。我所做的是改回一些我尝试过很多次但以前没有用过的旧代码。
我从 Web.config 中删除了 httpProtocol 东西。
我将 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));
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
并且在 GrantResourceOwnerCredentials() 的 ApplicationOAuthProvider.cs 中,我将此行添加到函数的顶部:
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
这是我以前多次尝试过的一些完全相同的代码,但这次我不知道是什么让它起作用了。我登录了我的电脑,当我回来尝试时,它突然工作了。这里有一些巫毒教的东西,但这可能是正确的方法。
我在使用跨源内容从我的前端(Node.js 和 Ajax)登录我的 Web Api 时遇到了一些问题。我收到以下错误:
XMLHttpRequest cannot load http://localhost:61102/Token. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 500.
这个问题只有在调用/Token登录的时候才会出现,我可以访问其他路由,完美注册。这是我的代码:
Startup.cs:
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
ConfigureAuth(app);
WebApiConfig.Register(config);
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(config);
}
Startup.Auth.cs:
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
}
并且我在 ApplicationOAuthProvider.cs
中将context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
放入 GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
我已经尝试寻找答案很长时间了,并且偶然发现了很多不同的答案,但这些答案对我来说都不起作用。不知道怎么了。
更新 - 添加了我的 ajax 脚本
import {URL} from '../constants/AuthConstants';
import request from 'reqwest';
import history from './HistoryService';
let router = null;
class AuthService {
login(email, password) {
console.log(URL.LOGIN);
var grant_type = 'password';
return request({
url: URL.LOGIN,
method: 'POST',
crossOrigin: true,
content-Type
data: {
grant_type, email, password
},
success: function(response) {
console.log("Yay! Login", response);
},
error: function(response) {
console.log("Error! Login", response);
}
});
}
}
您对 CORS 的使用与我过去使用的有所不同。我已经相对成功地完成了以下多次。
在您的 WebApi 项目中添加对 System.Web.Cors
的引用,并将以下内容添加到 WebApiConfig.cs
文件中的 Register
方法:
public static void Register(HttpConfiguration config)
{
config.SetCorsPolicyProviderFactory(new CorsPolicyFactory());
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
可以在此处找到更深入的教程:
http://tostring.it/2014/03/04/how-to-use-CORS-with-ASPNET-WebAPI-2/
天哪,我让它工作了。虽然不确定它是否好或正确的方法(可能不是,但它有效)。我所做的是愤怒地删除了代码中的 app.UseCors(CorsOptions.AllowAll);
和所有其他启用 cors 的东西,并将其添加到 <system.webServer>
:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:8080"/>
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
</customHeaders>
</httpProtocol>
我会将其标记为答案,因为它有效,但由于我不确定它是否是解决此问题的正确方法,请告诉我是否正确,我将更改 "correct answer" 内容。
编辑 - 正确的方法
使用上面的方法我可以注册和登录,但无法执行其他调用,例如 "api/values/1"(因为它在发送 [=36= 之前发送了 'OPTIONS' ] 之类的,我不想为其创建处理程序)。我所做的是改回一些我尝试过很多次但以前没有用过的旧代码。
我从 Web.config 中删除了 httpProtocol 东西。
我将 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));
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
并且在 GrantResourceOwnerCredentials() 的 ApplicationOAuthProvider.cs 中,我将此行添加到函数的顶部:
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
这是我以前多次尝试过的一些完全相同的代码,但这次我不知道是什么让它起作用了。我登录了我的电脑,当我回来尝试时,它突然工作了。这里有一些巫毒教的东西,但这可能是正确的方法。