Подтвердить что ты не робот

Проблемы с аутентификацией ASP.NET Forms на Phonegap (Android)

У меня есть ASP.NET MVC/Web API, где я реализовал аутентификацию форм для своего приложения Phonegap. Вход в систему выполняется путем отправки учетных данных пользователей через вызов JQuery Ajax следующим образом:

$.ajax({
    type: "POST",
    url: "/api/authentication/login",
    data: JSON.stringify({ Username: username, Password: password }),
    contentType: "application/json; charset=utf-8",
    dataType: "TEXT",
    statusCode: {
        200: function (response, status, xhr) {
            // successfully authenticated
            Backbone.history.navigate("/", { trigger: true });
        }
    }
});

Метод входа в backend выглядит следующим образом:

[ActionName("login")]
[AllowAnonymous]
public LoginResult Login(LoginCredentials credentials)
{
    // doing all kinds of things here

    // if valid credentials
    FormsAuthentication.SetAuthCookie(loginID, true);
    return loginResult;
}

У меня это в моем Web.config:

<authentication mode="Forms">
  <forms
    name=".ASPXAUTH"
    loginUrl="/login"
    defaultUrl="/home"
    protection="All"
    slidingExpiration="true"
    timeout="525600"
    cookieless="UseCookies"
    enableCrossAppRedirects="false"
    requireSSL="true"
    >
  </forms>
</authentication>

Теперь проблема с Android заключается в том, что cookie правильно настроен, и он работает с моими авторизованными методами после входа в систему, но иногда (часто), когда я закрываю приложение и открываю его снова, я больше не вхожу в систему Печенье больше нет, я не вижу его в запросе. Этого не должно произойти, потому что я установил тайм-аут на 525600. Я заметил, что эта проблема часто возникает, когда я закрываю приложение сразу после входа в систему. В другой руке, если я выйду из системы, а затем войдите в систему, не закрывая приложение, cookie будет сохранен правильно.

Но, если я получу cookie, чтобы придерживаться, большую часть времени logout ведет себя странно. Вот как я делаю запрос на выход:

$.ajax({
    type: "POST",
    url: "/api/authentication/logout",
    data: "{}",
    contentType: "application/json; charset=utf-8",
    dataType: "text"
    success: function (response) {
        // successfully logged out
        Backbone.history.navigate("api/login", { trigger: true });
    }
});

Бэкэнд:

[ActionName("logout")]
[AllowAnonymous]
public String Logout()
{
    FormsAuthentication.SignOut();

    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, "");
    cookie.Expires = DateTime.Now.AddYears(-1);
    HttpContext.Current.Response.Cookies.Add(cookie);

    return "home";
}

Теперь, похоже на проблему с логином, выход из системы сначала кажется успешным, и cookie больше не отправляется с любыми запросами. Но когда я закрываю приложение и открываю его снова, файл cookie возвращается, и я снова вошел в систему. Я вижу, что файл cookie имеет то же значение, что и тот, который, как я думал, я просто удалил, установив время его истечения в прошлое.

Я пробовал всевозможные трюки, например:

  • дополнительные перезагрузки после входа/выхода из системы (location.reload())
  • выполнение запроса logout/login несколько раз
  • выполнение запроса для других методов после входа/выхода из системы
  • 1-10 секундный тайм-аут между запросом входа/выхода и перезагрузкой
  • все виды изменений выше.

Аутентификация работает по назначению на iOS и Windows Phone. Проблема возникает только на Android (тестируется на KitKat и Lollipop). Никаких проблем с эмулятором Android, но на реальных устройствах и эмуляторе Visual Studios Android это происходит все время.

Я не знаю, в каком направлении идти отсюда. Есть ли что-то в Android WebView, которое может вызвать такое поведение? Есть что-то еще, что я могу проверить? Пожалуйста, помогите!

Я более чем счастлив предоставить дополнительную информацию, если это необходимо.

EDIT: Вдохновленный комментарием Фабиана, я изменил метод выхода:

FormsAuthentication.SignOut();

HttpCookie cookie = HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName];
cookie.Expires = DateTime.Now.AddYears(-1);
HttpContext.Current.Response.Cookies.Clear();
HttpContext.Current.Response.Cookies.Add(cookie);

return "home";

Вместо того, чтобы создавать новый файл cookie, я использовал его в ответе. Это не сработало.

Я также попробовал что-то, что я нашел отсюда: http://techblog.dorogin.com/2013/01/formsauthentication-gotcha-with-signout.html Это также не имело никакого значения, путь не был проблемой. Все еще ищете решение.

ДРУГОЕ ИЗМЕНЕНИЕ: Все еще не в состоянии найти решение для этого. Мне пришлось сделать ужасное обходное решение.

  • Вход: Я делаю две перезагрузки после входа в систему, а затем запрос на фиктивный метод. Кажется, что это работает каждый раз.
  • Выход: Я использую флаг, размещенный в localStorage, чтобы определить, вышел ли пользователь и выполнил выход из системы при запуске. Это всегда удаляет cookie правильно.

Я не доволен этими хаками, и я все еще надеюсь на лучшее решение.

4b9b3361

Ответ 1

PhoneGap загружает файлы из протокола file://. К сожалению, запросы перекрестного происхождения не разрешены, и если вы не открываете запросы на кросс-поиск со всех хостов *, эта проблема не будет разрешена.

Существует несколько способов исправления, но они очень длинные.

Загрузить Html из http://

Загрузка всего веб-сайта с веб-сервера вместо локального хранилища. Это устраняет все проблемы с запросами на перекрестный поиск. Преимущество - вам не нужно публиковать новую версию приложения при изменении пользовательского интерфейса. Но вам нужно будет реализовать очень мощное кэширование, и первое приложение для открытия времени займет больше времени.

Перехватить http:// и доставить локальные файлы

Как вы знаете, телефонная книга просто использует WebView, на всех платформах вы можете просто переопределить протокол Url, чтобы вставлять файлы из локального хранилища приложений. Это будет быстрее, и браузер подумает, что он загружает html с того же ресурса.

Настройка OAuth + настраиваемого заголовка для аутентификации

  • Перенаправление на страницу входа, размещенную на вашем сайте, говорит http://domain.com/api/login
  • После успешного входа в систему используйте PhoneGap localStorage (не браузер localStorage) для хранения авторизации.
  • Перейдите на свои локальные html-страницы из приложения и для каждого запроса json api, который вы отправляете на сервер, отправьте заголовок авторизации в виде отдельного заголовка в запросе ajax.
  • Настройте модуль авторизации, где вы можете вручную разрешить запрос asp.net, если ваша авторизация была отправлена ​​через пользовательский заголовок в запросе http

Ответ 2

Я считаю, что нашел решение. Версия Phonegap в файле config.xml cli-5.1.1, которая включает версию Android Phonegap 4.0.2 в соответствии с документация.

Проблема с версиями заключается в том, что, по-видимому, команда Android Phonegap окончательно устранила проблему хранения файлов cookie на версии 5.2.0. Его можно найти в примечания к выпуску как:

CB-10896 Мы никогда не включали файлы cookie в свой собственный WebView

Поэтому обновление вашей Phonegap до последней версии должно решить проблему.

Ответ 3

Согласно MSDN:

Метод FormsAuthentication.SignOut удаляет Информация о билетах формы-аутентификации из файла cookie.

И все, что вам нужно, чтобы вывести пользователя из системы. Вам не нужно истекать или удалять свой файл cookie. Просто измените Logout() на:

[ActionName("logout")]
[AllowAnonymous]
public String Logout()
{
    FormsAuthentication.SignOut();
    return "home";
}