สิ่งที่ฉันพยายามทำ
ฉันมี ASP.Net Core Web API แบ็กเอนด์ที่โฮสต์บน Azure Free Plan (ซอร์สโค้ด: https://github.com/killerrin/Portfolio-Backend )
ฉันมีเว็บไซต์ลูกค้าที่ฉันต้องการใช้ API นั้น แอปพลิเคชันไคลเอนต์จะไม่ถูกโฮสต์บน Azure แต่จะถูกโฮสต์บน Github Pages หรือบริการเว็บโฮสติ้งอื่นที่ฉันสามารถเข้าถึงได้ ด้วยเหตุนี้ชื่อโดเมนจะไม่ตรง
เมื่อมองถึงสิ่งนี้ฉันต้องเปิดใช้งาน CORS ทางฝั่ง Web API แต่ฉันได้ลองทุกอย่างเป็นเวลาหลายชั่วโมงแล้วและปฏิเสธที่จะทำงาน
ฉันมีการตั้งค่าไคลเอนต์ มันเป็นเพียงลูกค้าที่เรียบง่ายเขียนใน React.js ฉันกำลังเรียก API ผ่าน AJAX ใน Jquery ไซต์ React ใช้งานได้ดังนั้นฉันจึงไม่ทราบ การเรียก API ของ Jquery ทำงานได้ตามที่ฉันยืนยันในความพยายามที่ 1 นี่คือวิธีการโทร
var apiUrl = "http://andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication";
//alert(username + "|" + password + "|" + apiUrl);
$.ajax({
url: apiUrl,
type: "POST",
data: {
username: username,
password: password
},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var authenticatedUser = JSON.parse(response);
//alert("Data Loaded: " + authenticatedUser);
if (onComplete != null) {
onComplete(authenticatedUser);
}
},
error: function (xhr, status, error) {
//alert(xhr.responseText);
if (onComplete != null) {
onComplete(xhr.responseText);
}
}
});
สิ่งที่ฉันได้ลอง
ความพยายามที่ 1 - วิธีที่ 'เหมาะสม'
https://docs.microsoft.com/en-us/aspnet/core/security/cors
ฉันได้ทำตามบทช่วยสอนนี้บนเว็บไซต์ Microsoft เป็น T แล้วลองทั้ง 3 ตัวเลือกในการเปิดใช้งานได้ทั่วโลกใน Startup.cs การตั้งค่าบนตัวควบคุมทุกตัวและลองใช้กับทุกการกระทำ
ทำตามวิธีนี้ Cross Domain ใช้งานได้ แต่ทำงานบน Action เดียวบนคอนโทรลเลอร์เดี่ยว (POST to AccountController) เท่านั้น สำหรับทุกอย่างอื่นMicrosoft.AspNetCore.Cors
มิดเดิลแวร์ปฏิเสธที่จะตั้งค่าส่วนหัว
ฉันติดตั้งMicrosoft.AspNetCore.Cors
ผ่าน NUGET และเป็นเวอร์ชั่น1.1.2
นี่คือวิธีที่ฉันมีการตั้งค่าใน Startup.cs
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add Cors
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
// Add framework services.
services.AddMvc();
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new CorsAuthorizationFilterFactory("MyPolicy"));
});
...
...
...
}
// This method gets called by the runtime. Use this method to configure
//the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
// Enable Cors
app.UseCors("MyPolicy");
//app.UseMvcWithDefaultRoute();
app.UseMvc();
...
...
...
}
อย่างที่คุณเห็นฉันกำลังทำทุกอย่างตามที่บอก ฉันเพิ่ม Cors ก่อน MVC ทั้งสองครั้งและเมื่อไม่ได้ผลฉันพยายามใส่[EnableCors("MyPolicy")]
คอนโทรลเลอร์ทุกตัวเป็นอย่างนั้น
[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller
พยายาม 2 - เดียรัจฉานบังคับมัน
https://andrewlock.net/adding-default-security-headers-in-asp-net-core/
หลังจากพยายามหลายชั่วโมงก่อนหน้านี้ฉันคิดว่าฉันจะพยายามทำให้เป็นจริงโดยพยายามตั้งค่าส่วนหัวด้วยตนเองบังคับให้พวกเขาทำงานทุกครั้ง ฉันทำสิ่งนี้ตามบทช่วยสอนนี้เกี่ยวกับการเพิ่มส่วนหัวในทุก ๆ การตอบกลับด้วยตนเอง
นี่คือส่วนหัวที่ฉันเพิ่ม
.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")
นี่คือส่วนหัวอื่น ๆ ที่ฉันลองซึ่งล้มเหลว
.AddCustomHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "content-type, accept, X-PINGOTHER")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Host, User-Agent, Accept, Accept: application/json, application/json, Accept-Language, Accept-Encoding, Access-Control-Request-Method, Access-Control-Request-Headers, Origin, Connection, Content-Type, Content-Type: application/json, Authorization, Connection, Origin, Referer")
ด้วยวิธีนี้ส่วนหัว Cross Site นั้นได้ถูกนำไปใช้อย่างเหมาะสมและพวกมันจะปรากฏในคอนโซลนักพัฒนาซอฟต์แวร์ของฉันและในบุรุษไปรษณีย์ อย่างไรก็ตามปัญหาคือในขณะที่มันผ่านการAccess-Control-Allow-Origin
ตรวจสอบเว็บเบราว์เซอร์โยนแบบ hissy พอดี (ฉันเชื่อ) Access-Control-Allow-Headers
ระบุ415 (Unsupported Media Type)
ดังนั้นวิธีเดรัจฉานบังคับไม่ทำงานเช่นกัน
ในที่สุด
มีใครได้รับสิ่งนี้ในการทำงานและสามารถยืมมือหรือเพียงแค่สามารถชี้ให้ฉันไปในทิศทางที่ถูกต้อง?
แก้ไข
ดังนั้นเพื่อให้การเรียก API ผ่านไปได้ฉันต้องหยุดใช้ JQuery และเปลี่ยนเป็นXMLHttpRequest
รูปแบบPure Javascript
พยายาม 1
ฉันจัดการที่จะได้รับMicrosoft.AspNetCore.Cors
ในการทำงานโดยทำตามคำตอบ MindingData ยกเว้นในConfigure
วิธีการวางก่อนapp.UseCors
app.UseMvc
นอกจากนี้เมื่อผสมกับ Javascript API Solution options.AllowAnyOrigin()
เพื่อรองรับสัญลักษณ์ตัวแทนก็เริ่มทำงานได้เช่นกัน
พยายาม 2
ดังนั้นฉันจึงพยายามรับ 2 (เดรัจฉานบังคับ) เพื่อให้ทำงาน ... โดยมีข้อยกเว้นเพียงอย่างเดียวที่ไวด์การ์ดสำหรับAccess-Control-Allow-Origin
ใช้งานไม่ได้และดังนั้นฉันจึงต้องตั้งค่าโดเมนที่สามารถเข้าถึงได้ด้วยตนเอง
เห็นได้ชัดว่ามันไม่เหมาะเพราะฉันแค่ต้องการให้ WebAPI นี้เปิดกว้างสำหรับทุกคน แต่อย่างน้อยก็เหมาะสำหรับฉันในเว็บไซต์อื่นซึ่งหมายความว่าเป็นการเริ่มต้น
app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
.AddDefaultSecurePolicy()
.AddCustomHeader("Access-Control-Allow-Origin", "http://localhost:3000")
.AddCustomHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, Authorization"));
415 (Unsupported Media Type)
ปัญหากำหนดหัวข้อการร้องขอไปContent-Type
application/json