NiceToMytyuk
NiceToMytyuk

Reputation: 4317

Redirect for non authorized users not working in ajax request

I have a Cookie based authentication in my webapp to which a sub application make some ajax requests to get the data from db.

the issue is that if the user is not authenticated i redirect him to expired.html, in test mode if i just run in browser or postman an api call like example.com/api/test without getting first the authentication cookie i'm correctly redirected to expired.html. the issue comes when i try to call that api via ajax so by making a simple .get request as the following:

function getPlu(codplu, callback){
      let api = 'https://www.example.it/api/plu/?codplu=' + codplu
      $.get( api, callback );
}
  getPlu('COPERTI', callback => {
       ...
  });

i just get the response from api with code 302 and a .get to expired.html with code 304 but the user still is not redirected to expired.html

So as you can see the status code for that api request is 302 and location should be expired.html BUT it's not getting redirected.

enter image description here

Might it be that browser doesn't handle automatically ajax redirects and i need to do it via client-side (redirect if status.code == 302) or i could fix it via server side?

Here is how the authentication makes the redirect

        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options => {
            options.Cookie.Name = "AUTH_TOKEN";
            options.Cookie.MaxAge = TimeSpan.FromMinutes(120);
            options.Events = new CookieAuthenticationEvents()
            {
                OnRedirectToLogin = (context) =>
                {
                    context.HttpContext.Response.Redirect("https://www.example.it/vmenu/expired.html");
                    return Task.CompletedTask;
                }
            };
        });

Upvotes: 2

Views: 582

Answers (1)

Vitox
Vitox

Reputation: 4424

Just to make this answer more clear:

jQuery's ajax uses the XMLHttpRequest object and its methods to execute requests. XMLHttpRequest will follow redirects automatically. Since it's XMLHttpRequest who does that, jQuery's ajax function doesn't even know about it. It only receives the final response, which in the OP's case is 200 Ok (or 304 Not Modified as OP posted).

Also, since the request is made by jQuery/XMLHttpRequest, the client view is not changed if a request or a redirect is executed. Everything is only in the browser's "behind execution".

Since all redirects are executed automatically by XMLHttpRequest, and jQuery is not able to tell if a redirect was made, the most reliable way (and that's the most important thing to me) is handle it manually:

1 - On server side, when unauthenticated request, add a custom header to the response, and respond with 200 OK:

OnRedirectToLogin = (context) =>
{
    context.Response.StatusCode = (int)System.Net.HttpStatusCode.OK;
    context.Response.Headers.Add("X-Unauthenticated-Redirect", "https://www.example.it/vmenu/expired.html");
    return Task.CompletedTask;
}

2 - On client side, just check if this custom header exists. If it does, redirect manually using window.location:

var redirectHeader = jqXHR.getResponseHeader('X-Unauthenticated-Redirect');
if (redirectHeader.length > 0) {
    window.location = redirectHeader;
}


Just for reference, from XMLHttpRequest docs:

If the origin of the URL conveyed by the Location header is same origin with the XMLHttpRequest origin and the redirect does not violate infinite loop precautions, transparently follow the redirect while observing the same-origin request event rules.

Upvotes: 1

Related Questions