Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/198.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Phonegap(Android)上的ASP.NET表单身份验证问题_Android_Asp.net_Cordova_Authentication_Cookies - Fatal编程技术网

Phonegap(Android)上的ASP.NET表单身份验证问题

Phonegap(Android)上的ASP.NET表单身份验证问题,android,asp.net,cordova,authentication,cookies,Android,Asp.net,Cordova,Authentication,Cookies,我有一个ASP.NET MVC/Web API后端,在那里我为我的Phonegap应用程序实现了表单身份验证。通过jQuery Ajax调用发送用户凭据来执行登录,如下所示: $.ajax({ type: "POST", url: "/api/authentication/login", data: JSON.stringify({ Username: username, Password: password }), contentType: "applicati

我有一个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 });
        }
    }
});
[ActionName("login")]
[AllowAnonymous]
public LoginResult Login(LoginCredentials credentials)
{
    // doing all kinds of things here

    // if valid credentials
    FormsAuthentication.SetAuthCookie(loginID, true);
    return loginResult;
}
后端登录方法如下所示:

$.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 });
        }
    }
});
[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>
后端:

[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的值与我认为刚删除的cookie的值相同

我试过各种各样的把戏,比如:

  • 登录/注销后额外重新加载(
    location.reload()
  • 多次执行注销/登录请求
  • 在登录/注销后执行对其他方法的请求
  • 登录/注销请求与重新加载之间的1-10秒超时
  • 以上的各种变化
身份验证在iOS和Windows Phone上正常工作。这个问题只在Android上出现(在KitKat和棒棒糖上测试)。在Android emulator上没有问题,但在真实设备和Visual Studio Android emulator上,这种情况经常发生

我不知道从这里往哪个方向走。Android WebView中是否存在可能导致此类行为的内容?还有什么我可以测试的吗?请帮忙

如果需要,我非常乐意提供更多信息

编辑: 受Fabian评论的启发,我将注销方法更改为:

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,而是使用了响应中的cookie。它不起作用

我也尝试了一些我在这里发现的东西:那也没什么区别,路径不是问题。仍在寻找解决方案

另一次编辑: 仍然无法找到解决方案。我不得不做一个可怕的变通

  • 登录:我在登录后重新加载两次,然后请求 一种虚拟方法。这似乎每次都有效
  • 注销:我使用放置在localStorage中的标志来确定用户是否已注销,并在启动时执行注销。这总是正确地删除cookie
我对这些黑客行为不满意,我仍然希望有更好的解决方案。

根据:

FormsAuthentication.SignOut方法将删除 表单来自cookie的身份验证票证信息

这就是用户注销所需的全部内容。您不需要过期或删除cookie本身。只需将您的
注销()更改为:

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

我相信我已经找到了解决办法。config.xml文件上的Phonegap版本是cli-5.1.1,根据配置文件,其中包括Android Phonegap版本4.0.2

这些版本的问题在于,Android Phonegap团队似乎最终解决了版本5.2.0上的cookie存储问题。可在以下目录中找到:

我们从未在WebView上启用Cookie


因此,将Phonegap更新到最新版本应该可以解决这个问题

PhoneGap从
file://
协议加载文件。不幸的是,不允许跨源请求,除非您打开来自所有主机的跨源请求
*
,否则此问题将无法解决

有多种方法可以解决这个问题,但它们确实很长

http://
加载Html

从web服务器而不是本地存储加载整个网站。这将消除跨来源请求的所有问题。好处是,当您更改UI时,不需要发布新版本的应用程序。但您必须实现非常强大的缓存,第一次打开应用程序需要更长的时间

拦截
http://
并交付本地文件

正如您所知,phonegap只是使用WebView,在所有平台上,您都可以简单地覆盖Url协议,从应用程序的本地存储中插入文件。这样会更快,浏览器会认为它是从同一资源加载html

为身份验证设置OAuth+自定义头文件

  • 重定向到网站上托管的登录页面,如
    http://domain.com/api/login
  • 成功登录后,使用
    PhoneGap localStorage
    (不是浏览器的localStorage)存储授权
  • 从应用程序导航到您的本地html页面,对于发送到服务器的每个json api请求,在ajax请求中将授权头作为单独的头发送
  • 设置授权模块,如果您的授权是通过http请求中的自定义标头发送的,则可以在其中手动授权asp.net请求

  • 我认为你应该发布你的安卓代码来获取更多信息。你说的“安卓代码”是什么意思?我说的是Phonegap应用程序,所有相关的JS代码都在讨论中。我的意思是,如何设置WebView Phonegap(Cordova API)是为我“设置”WebView。我只能通过以下方式控制应用程序的设置。AndroidManifest.xml是根据这些设置在构建中创建的。能否尝试将HttpContext.Current.Response.Cookies.Add(cookie)替换为Response.Cookies[System.Web.Security.FormsAuthentication.FormsCookieName].Expires=DateTime.Now.AddYears(-1)。我不确定它会改变什么,只是为了防止您最终创建多个cookie,并且它使用了错误的cookie。您在哪里找到了OP的config.xml文件?我不认为我得到了这个问题。你能说得更具体一点吗?不幸的是,这并没有解决问题。我现在正在使用cli-6.3.0(Android 5.2.1),登录/注销行为完全相同。感谢您提供详细的答案。我认为你是对的,解决这个问题的正确方法是改变身份验证方法