2016-01-11 3 views
3

Если пользователь находится на странице в течение длительного времени, а сеанс заканчивается, если они продолжают совершать AJAX-вызов после сеанс уже истек. Вместо получения объекта JSON вместо этого он получает HTML-адрес страницы входа.ASP.NET MVC & Angular: после окончания сессии функция Angular Factory возвращает HTML-страницу входа вместо объекта JSON

В идеале я пытаюсь сделать так, чтобы он перенаправлялся на страницу входа в систему.

Есть ли способ обнаружить это?

У меня уже есть ActionFilterAttribute, который работает для не-AJAX звонки следующим образом:

public class VerifySessionAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     var userId = filterContext.HttpContext.Session["UserId"]; 
     var userName = filterContext.HttpContext.Session["UserName"]; 

     if (userId == null || userName == null) 
     { 
      filterContext.Result = new RedirectResult(string.Format("/Account/Login")); 
      return; 
     } 

     base.OnActionExecuting(filterContext); 
    } 
} 

Но это не получить удар по сценарию выше во время AJAX-вызовов.

Я также попробовал перехватчик .. что-то вроде этого:

app.factory('httpAuthInterceptor', function ($q) { 
    return { 
     'responseError': function (response) { 
      // NOTE: detect error because of unauthenticated user 
      if ([401, 403].indexOf(response.status) >= 0) { 
       // redirecting to login page 
       //$state.go('home'); 
       $window.location.href = '/Account/Login'; 
       return response; 
      } else { 
       return $q.reject(rejection); 
      } 
     } 
    }; 
}) 

app.config(function ($httpProvider) { 
    $httpProvider.interceptors.push('httpAuthInterceptor'); 
}); 

Но в том же сценарии, кажется, не попал туда, а также в течение истекшего сеанса/AJAX вызова

Есть ли что-нибудь, что я могу сделать, чтобы обнаружить это? Когда сеанс истек, я просто хочу, чтобы перенаправить на страницу входа в систему .. Спасибо за любую помощь

EDIT: вот как я делаю мои звонки

app.factory('HeadlinesFactory', ['$http', function ($http) { 
    var HeadlinesFactory = {}; 

    HeadlinesFactory.getShowsForClient = function (clientId) { 
     return $http({ 
      method: 'POST', 
      url: '/Show/GetShowsForClient', 
      data: { clientId: JSON.stringify(clientId) } 
     }); 
    }; 
    //etc 

edit2: как все мои контроллеры похожи. Кроме моего счет контроллера, где я поставил VerifySession перед всем, кроме страницы входа, чтобы предотвратить цикл перенаправляет:

[Authorize] 
[CustomFilters.VerifySession] 
public class ShowController : Controller 
{ ... } 
+0

В качестве возврата 'RedirectResult' это означает, что статус ответа будет равен 302, поэтому вы должны проверить статус на 302 в своем перехватчике. –

+0

@ HamletHakobyan спасибо за ваш вклад. из моего тестирования кажется, что, когда сессия истекла, и я пытаюсь сделать ее AJAX, она не входит в перехватчик вообще, поэтому независимо от того, что я там ввел, это не имеет значения из-за что. Пожалуйста, хотя, если я ошибаюсь в этом и, возможно, что-то неправильно, дайте мне знать. – user1189352

ответ

3

Ajax запросы не будут обрабатывать перенаправление запросов по соображениям безопасности. Кроме того, поскольку вы возвращаете результат перенаправления, код статуса 401/403 не генерируется, а возвращается 302.

Что вы можете сделать, это расширить свой фильтр, чтобы условно логизировать, основываясь на том, является ли запрос ajax-запросом. Кроме того, исходя из ваших комментариев, похоже, что создание нового атрибута Authorize будет правильным путем, так как вы можете просто заменить атрибут Authorize по умолчанию своей собственной логикой.

public class VerifySessionAttribute : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      if (filterContext.HttpContext.Request.IsAjaxRequest()) 
      { 
       filterContext.HttpContext.Response.StatusCode = 401; 
       filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = 
         true; 
      } 
      else 
      { 
       filterContext.Result = new RedirectResult(string.Format("/Account/Login")); 
       return; 
      } 
     } 
    } 
} 

Это позволит вашему Угловому перехватчику подобрать запрос и обработать его соответствующим образом.

Поскольку IsAjaxRequest явно указывает на «X-Requested-With»: «XMLHttpRequest», а AngularJS больше не предоставляет этот заголовок с запросами Ajax, вы можете добавить конфигурацию в $ httpProvider, чтобы всегда включать заголовок.

app.config(['$httpProvider', function ($httpProvider) { 
    $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 
}]); 
+0

Привет, Дэвид благодарен за ответ. Я поставил точку останова в своем ActionFilter, которую я разместил выше, и кажется, что он не входит туда ВСЕ, как только сессия истекло, поэтому я чувствую, что это не сработает ...Я ошибаюсь? Я хочу, чтобы ты был прав. Я действительно пробовал это безрезультатно, к сожалению, – user1189352

+0

Как вы применяете свой атрибут? Используется ли он в сочетании с атрибутами '[Authorize]'? –

+0

Да. Я поставил его перед всеми моими контроллерами. Я сделал EDIT2, чтобы показать вам – user1189352