重定向时 Google 身份验证的 ASP .NET Core CORS 问题
一直遵循此教程,以便在我的 Web API 和客户端上实现 Google 身份验证侧面(使用 React 和 axios 执行请求)身份验证过程因 CORS 问题而中断,我正在努力解决它:
访问“https://accounts.google.com/o/oauth2/v2/auth?(etc)”处的 XMLHttpRequest(从“https://localhost:44320/Photo/b997d788-3812-41d0-”重定向)来自来源“https://localhost:8080”的 a09d-1a597eee9bad') 已被 CORS 策略阻止:否请求的资源上存在“Access-Control-Allow-Origin”标头。
这是 Startup.cs 文件:
namespace rvc
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
});
});
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(options =>
{
options.LoginPath = "/account/google-login";
}).AddGoogle(options =>
{
options.ClientId = "clientId";
options.ClientSecret = "secret";
});
services.AddScoped<PhotoService>();
services.AddScoped<TagService>();
services.AddScoped(_ => new BlobServiceClient(Configuration.GetConnectionString("AzureBlobStorage")));
services.AddDbContext<Data.DataContext>(x => x.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
});
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "rvc", Version = "v1" }); });
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "rvc v1"));
}
app.UseHttpsRedirection();
if (env.IsProduction())
{
app.UseSpa(spa => { });
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "client")),
EnableDefaultFiles = true
});
}
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}
}
}
调用 Route("google-login") 但未到达 Url.Action("GoogleResponse")。这些是 Google 身份验证方法:
namespace rvc.Controllers;
[AllowAnonymous, Route("account")]
public class AccountController : Controller
{
[Route("google-login")]
public IActionResult GoogleLogin()
{
var properties = new AuthenticationProperties {RedirectUri = Url.Action("GoogleResponse")};
return Challenge(properties, GoogleDefaults.AuthenticationScheme);
}
[Route("google-response")]
public async Task<IActionResult> GoogleResponse()
{
var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var claims = result.Principal?.Identities.FirstOrDefault()
?.Claims.Select(claim => new
{
claim.Issuer,
claim.OriginalIssuer,
claim.Type,
claim.Value
});
return Json(claims);
}
}
Been following this tutorial in order to implement Google authentication in my web API but on the client side (using React and axios to do the request) the authentication process gets interrupted with this CORS issue and I'm struggling to sort it out:
Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/auth?(etc)' (redirected from 'https://localhost:44320/Photo/b997d788-3812-41d0-a09d-1a597eee9bad') from origin 'https://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
This is the Startup.cs file:
namespace rvc
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
});
});
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(options =>
{
options.LoginPath = "/account/google-login";
}).AddGoogle(options =>
{
options.ClientId = "clientId";
options.ClientSecret = "secret";
});
services.AddScoped<PhotoService>();
services.AddScoped<TagService>();
services.AddScoped(_ => new BlobServiceClient(Configuration.GetConnectionString("AzureBlobStorage")));
services.AddDbContext<Data.DataContext>(x => x.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
});
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "rvc", Version = "v1" }); });
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "rvc v1"));
}
app.UseHttpsRedirection();
if (env.IsProduction())
{
app.UseSpa(spa => { });
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "client")),
EnableDefaultFiles = true
});
}
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}
}
}
The Route("google-login") gets called but the Url.Action("GoogleResponse") is not reached. These are the Google Authentication methods:
namespace rvc.Controllers;
[AllowAnonymous, Route("account")]
public class AccountController : Controller
{
[Route("google-login")]
public IActionResult GoogleLogin()
{
var properties = new AuthenticationProperties {RedirectUri = Url.Action("GoogleResponse")};
return Challenge(properties, GoogleDefaults.AuthenticationScheme);
}
[Route("google-response")]
public async Task<IActionResult> GoogleResponse()
{
var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var claims = result.Principal?.Identities.FirstOrDefault()
?.Claims.Select(claim => new
{
claim.Issuer,
claim.OriginalIssuer,
claim.Type,
claim.Value
});
return Json(claims);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这可能是因为您在服务器上使用了重定向,这会触发 CORS(即使您在服务器上允许这样做)。
您必须以其他方式将重定向 URL 返回到前端,从前端应用程序捕获它,然后调用您需要调用的 URL。
This is probably because from the server you use redirect, which triggers CORS (even if from your server you allow it).
you have to return the redirect URL to your front-end in some other way, capture it from the front-end app and then call the URL you need to invoke.