c# - ASP.net Core WebAPI में CORS को कैसे सक्षम करें




rest asp.net-core (8)

MindsData के उत्तर में आपकी टिप्पणी के आधार पर, इसका आपके CORS से कोई लेना-देना नहीं है, यह ठीक काम कर रहा है।

आपकी नियंत्रक कार्रवाई गलत डेटा लौटा रही है। HttpCode 415 का अर्थ है, "असमर्थित मीडिया प्रकार"। ऐसा तब होता है जब आप या तो कंट्रोलर को गलत फॉर्मेट पास करते हैं (यानी एक कंट्रोलर को एक्सएमएल जो केवल जौन को स्वीकार करता है) या जब आप गलत टाइप लौटाते हैं (कंट्रोलर में एक्सएमएल लौटाते हैं जिसे केवल एक्सएमएल वापस करने की घोषणा की जाती है)।

बाद में एक के लिए [Produces("...")] अस्तित्व की जाँच करें

मैं क्या करने की कोशिश कर रहा हूं

मेरे पास एक बैकएंड ASP.Net कोर वेब एपीआई है जो एक एज़्योर फ्री प्लान (स्रोत कोड: https://github.com/killerrin/Portfolio-Backend ) पर होस्ट किया गया है।

मेरे पास एक क्लाइंट वेबसाइट भी है जिसे मैं उस एपीआई का उपभोग करना चाहता हूं। क्लाइंट एप्लिकेशन को Azure पर होस्ट नहीं किया जाएगा, बल्कि इसे Github Pages या किसी अन्य वेब होस्टिंग सेवा पर होस्ट किया जाएगा जिसकी मुझे एक्सेस है। इस वजह से डोमेन नाम लाइन नहीं होंगे।

इसे देखते हुए, मुझे वेब एपीआई की तरफ कॉर्स को सक्षम करने की आवश्यकता है, हालांकि मैंने अभी कई घंटों के लिए सब कुछ करने की कोशिश की है और यह काम करने से इनकार कर रहा है।

मेरे पास क्लाइंट सेटअप कैसे है यह React.js में लिखा गया एक साधारण क्लाइंट है। मैं AJAX के माध्यम से 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 वेबसाइट पर इस ट्यूटोरियल को एक टी तक फॉलो किया है, इसे Startup.cs में ग्लोबली सक्षम करने के सभी 3 विकल्पों को आज़माते हुए, इसे हर कंट्रोलर पर सेट करके हर एक्शन पर आज़माया।

इस पद्धति का अनुसरण करते हुए, क्रॉस डोमेन काम करता है, लेकिन केवल एक ही नियंत्रक पर एक क्रिया पर (POST से खाता नियंत्रक)। बाकी सब के लिए, Microsoft.AspNetCore.Cors मिडलवेयर हेडर सेट करने से इनकार करता है।

मैंने NUGET के माध्यम से Microsoft.AspNetCore.Cors स्थापित किया है और संस्करण 1.1.2

यहां बताया गया है कि स्टार्टअप में यह कैसे सेटअप है

    // 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();

        ...
        ...
        ...
    }

जैसा कि आप देख सकते हैं, मैं सब कुछ बता रहा हूं। मैं 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")

इस पद्धति के साथ, क्रॉस साइट हेडर को ठीक से लागू किया जा रहा है और वे मेरे डेवलपर कंसोल और पोस्टमैन में दिखाई देते हैं। समस्या यह है कि जब यह Access-Control-Allow-Origin चेक पास करता है, वेबब्रोसर 415 (Unsupported Media Type) बताते हुए Access-Control-Allow-Headers हेडर्स पर एक हसी फिट बैठता है।

तो जानवर बल विधि भी काम नहीं करती है

आखिरकार

क्या किसी ने इसे काम करने के लिए दिया है और एक हाथ उधार दे सकता है, या बस मुझे सही दिशा में इंगित करने में सक्षम है?

संपादित करें

तो जाने के लिए एपीआई कॉल प्राप्त करने के लिए, मुझे JQuery का उपयोग करना बंद करना होगा और एक शुद्ध जावास्क्रिप्ट XMLHttpRequest प्रारूप में स्विच करना होगा।

प्रयास 1

मैं MindsData के उत्तर का पालन करके Microsoft.AspNetCore.Cors को प्राप्त करने में कामयाब रहा, app.UseCors से पहले app.UseMvc डालते हुए app.UseCors मेथड को छोड़कर।

इसके अलावा, जब जावास्क्रिप्ट एपीआई सॉल्यूशन options.AllowAnyOrigin() साथ मिलाया जाता है options.AllowAnyOrigin() वाइल्डकार्ड सपोर्ट के लिए ऑलवॉइन options.AllowAnyOrigin() भी काम करना शुरू कर दिया है।

प्रयास २

इसलिए मैं काम करने के लिए प्रयास 2 (इसे मजबूर करने के लिए) करने में कामयाब रहा हूं ... एकमात्र अपवाद के साथ जो Access-Control-Allow-Origin लिए वाइल्डकार्ड काम नहीं करता है और जैसे कि मुझे उन डोमेन को मैन्युअल रूप से सेट करना होगा जिनकी पहुंच है यह करने के लिए।

इसका स्पष्ट रूप से आदर्श नहीं है क्योंकि मैं चाहता हूं कि यह वेबएपीआई सभी के लिए खुली हो, लेकिन यह मेरे लिए एक अलग साइट पर काम करता है, जिसका मतलब है कि यह एक शुरुआत है

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"));

उपरोक्त प्रक्रियाओं में से किसी ने भी मदद नहीं की और मैंने तब article पढ़ा जो इस मुद्दे को हल करता है।

नीचे कोड है।

public void ConfigureServices(IServiceCollection services)
{
    // Add service and create Policy with options
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials() );
    });


    services.AddMvc(); 
}

तथा

public void Configure(IApplicationBuilder app)
{
    // ...

    // global policy - assign here or on each controller
    app.UseCors("CorsPolicy");

और मेरे एक्शनमेथोड के शीर्ष पर

[EnableCors("CorsPolicy")]

मुझे काम करने के लिए ऊपर MindsData का उत्तर मिला, लेकिन मुझे Microsoft.AspNetCore.Cors के बजाय Microsoft.AspNet.Cors का उपयोग करना था। मैं Visual Studio 2019 में .netCore वेब एप्लिकेशन एपीआई परियोजना का उपयोग कर रहा हूं


मुझे लगता है कि यदि आप अपने स्वयं के कोरस मिडलवेयर का उपयोग करते हैं, तो आपको यह सुनिश्चित करने की आवश्यकता है कि मूल हेडर की जांच करके यह वास्तव में कॉर्स अनुरोध है।

 public class CorsMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IMemoryCache _cache;
    private readonly ILogger<CorsMiddleware> _logger;

    public CorsMiddleware(RequestDelegate next, IMemoryCache cache, ILogger<CorsMiddleware> logger)
    {
        _next = next;
        _cache = cache;
        _logger = logger;
    }
    public async Task InvokeAsync(HttpContext context, IAdministrationApi adminApi)
    {
        if (context.Request.Headers.ContainsKey(CorsConstants.Origin) || context.Request.Headers.ContainsKey("origin"))
        {
            if (!context.Request.Headers.TryGetValue(CorsConstants.Origin, out var origin))
            {
                context.Request.Headers.TryGetValue("origin", out origin);
            }

            bool isAllowed;
            // Getting origin from DB to check with one from request and save it in cache 
            var result = _cache.GetOrCreateAsync(origin, async cacheEntry => await adminApi.DoesExistAsync(origin));
            isAllowed = result.Result.Result;

            if (isAllowed)
            {
                context.Response.Headers.Add(CorsConstants.AccessControlAllowOrigin, origin);
                context.Response.Headers.Add(
                    CorsConstants.AccessControlAllowHeaders,
                    $"{HeaderNames.Authorization}, {HeaderNames.ContentType}, {HeaderNames.AcceptLanguage}, {HeaderNames.Accept}");
                context.Response.Headers.Add(CorsConstants.AccessControlAllowMethods, "POST, GET, PUT, PATCH, DELETE, OPTIONS");

                if (context.Request.Method == "OPTIONS")
                {
                    _logger.LogInformation("CORS with origin {Origin} was handled successfully", origin);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    return;
                }

                await _next(context);
            }
            else
            {
                if (context.Request.Method == "OPTIONS")
                {
                    _logger.LogInformation("Preflight CORS request with origin {Origin} was declined", origin);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    return;
                }

                _logger.LogInformation("Simple CORS request with origin {Origin} was declined", origin);
                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                return;
            }
        }

        await _next(context);
    }

मेरे लिए, इसका उस कोड से कोई लेना-देना नहीं था जिसका मैं उपयोग कर रहा था। एज़्योर के लिए हमें ऐप सेवा की सेटिंग्स में जाना था, साइड मेनू पर प्रविष्टि "CORS"। वहाँ मुझे उस डोमेन को जोड़ना था जिससे मैं सामान का अनुरोध कर रहा था। एक बार जब मैं उस में था, सब कुछ जादू था।


मैंने अपना मिडलवेयर क्लास बनाया जो मेरे लिए काम करता था, मुझे लगता है कि .net कोर मिडलवेयर क्लास में कुछ गड़बड़ है

public class CorsMiddleware
{
    private readonly RequestDelegate _next;

    public CorsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext httpContext)
    {
        httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
        httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
        return _next(httpContext);
    }
}

// Extension method used to add the middleware to the HTTP request pipeline.
public static class CorsMiddlewareExtensions
{
    public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CorsMiddleware>();
    }
}

और इसे स्टार्टअप में इस तरह से उपयोग किया

app.UseCorsMiddleware();

के answer पर विस्तार करने के लिए, मैंने पाया कि मुझे अभी भी अपने उपयोग के मामले के लिए .NET कोर 2.1-प्रीव्यू में अनुरोधों के लिए विकल्प प्रतिक्रिया की आपूर्ति करने की आवश्यकता है:

// https://.com/a/45844400
public class CorsMiddleware
{
  private readonly RequestDelegate _next;

  public CorsMiddleware(RequestDelegate next)
  {
    _next = next;
  }

  public async Task Invoke(HttpContext context)
  {
    context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
    context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    // Added "Accept-Encoding" to this list
    context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Accept-Encoding, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
    context.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
    // New Code Starts here
    if (context.Request.Method == "OPTIONS")
    {
      context.Response.StatusCode = (int)HttpStatusCode.OK;
      await context.Response.WriteAsync(string.Empty);
    }
    // New Code Ends here

    await _next(context);
  }
}

और फिर Startup.cs में जैसे मिडलवेयर को सक्षम किया

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.UseMiddleware(typeof(CorsMiddleware));
  // ... other middleware inclusion such as ErrorHandling, Caching, etc
  app.UseMvc();
}

jQuery.support.cors = true; जोड़ने का प्रयास करें jQuery.support.cors = true; अजाक्स कॉल से पहले

यह भी हो सकता है कि आपके द्वारा एपीआई को भेजा गया डेटा विस्की हो,

निम्नलिखित JSON फ़ंक्शन को जोड़ने का प्रयास करें

        var JSON = JSON || {};

    // implement JSON.stringify serialization
    JSON.stringify = JSON.stringify || function (obj) {

        var t = typeof (obj);
        if (t != "object" || obj === null) {

            // simple data type
            if (t == "string") obj = '"' + obj + '"';
            return String(obj);

        }
        else {

            // recurse array or object
            var n, v, json = [], arr = (obj && obj.constructor == Array);

            for (n in obj) {
                v = obj[n]; t = typeof (v);

                if (t == "string") v = '"' + v + '"';
                else if (t == "object" && v !== null) v = JSON.stringify(v);

                json.push((arr ? "" : '"' + n + '":') + String(v));
            }

            return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
        }
    };

    // implement JSON.parse de-serialization
    JSON.parse = JSON.parse || function (str) {
        if (str === "") str = '""';
        eval("var p=" + str + ";");
        return p;
    };

फिर आपके डेटा में: ऑब्जेक्ट इसे में बदलें

    data: JSON.stringify({
        username: username,
        password: password
    }),





cross-domain