Редирект для неавторизованных пользователей, не работающих в запросе ajax - PullRequest
1 голос
/ 29 мая 2020

У меня есть аутентификация на основе Cook ie в моем веб-приложении, к которой вспомогательное приложение делает несколько ajax запросов для получения данных из базы данных.

проблема в том, что если пользователь не аутентифицирован, я перенаправьте его на expired.html, в тестовом режиме, если я просто запустил в браузере или почтальоне вызов API, например example.com/api/test, не получив сначала аутентификационный кулинар ie, я правильно перенаправлен на expired.html. проблема возникает, когда я пытаюсь вызвать этот api через ajax, поэтому, сделав простой запрос .get следующим образом:

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

я просто получаю ответ от api с кодом 302 и .get на expired.html с кодом 304, но пользователь по-прежнему не перенаправлен на expired.html

Итак, как вы можете видеть, код состояния для этого запроса api - 302, а местоположение должно быть expired.html НО он не перенаправляется.

enter image description here

Может быть, браузер не обрабатывает автоматически ajax перенаправления, и мне нужно сделать это через клиент - сторона (перенаправить, если status.code == 302), или я могу исправить это на стороне сервера?

Вот как аутентификация выполняет перенаправление

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

1 Ответ

1 голос
/ 29 мая 2020

Чтобы сделать этот ответ более ясным:

jQuery s ajax использует объект XMLHttpRequest и его методы для выполнения запросов. XMLHttpRequest будет автоматически следовать за перенаправлениями. Поскольку это делает XMLHttpRequest, функция jQuery ajax даже не знает об этом. Он получает только окончательный ответ, который в случае OP равен 200 Ok (или 304 Not Modified as OP отправлен).

Кроме того, поскольку запрос выполняется jQuery / XMLHttpRequest, представление клиента не изменяется, если выполняется запрос или редирект . Все только в браузере «за исполнением».

Поскольку все перенаправления выполняются автоматически XMLHttpRequest, а jQuery не может определить, было ли перенаправление выполнено, самый надежный способ (и это для меня самое главное) - обрабатывать его вручную:

1 - На стороне сервера, когда запрос не аутентифицирован, добавьте в ответ настраиваемый заголовок и ответьте 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 - На стороне клиента просто проверьте, существует ли этот настраиваемый заголовок. Если это так, перенаправьте вручную, используя window.location:

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

Для справки, из документов XMLHttpRequest:

Если источник URL, передаваемый заголовком Location, совпадает с источником XMLHttpRequest и перенаправление не нарушает бесконечные меры предосторожности l oop, прозрачно следуйте перенаправление с соблюдением правил обработки событий запроса того же происхождения.

...