在 iOS Safari 上的浏览​​器会话之间未保存 Cookie

Posted

技术标签:

【中文标题】在 iOS Safari 上的浏览​​器会话之间未保存 Cookie【英文标题】:Cookies not saved between browser sessions on iOS Safari 【发布时间】:2014-09-07 00:46:53 【问题描述】:

我有一个用户可以登录的 MVC 4 网站,我保存了一个包含他们会话信息的 cookie,这样他们就不必再次登录。

public void SetCookie(HttpCookie cookie)

    HttpContext.Current.Response.Cookies.Set(cookie);

这适用于桌面设备,但是当我在 ios 上运行它时,它不能 100% 运行。如果我在移动浏览器(Chrome 或 Safari)中至少打开 1 个页面,然后导航回我的网站,则会找到我的会话 cookie,我不必登录。但是,如果我关闭该浏览器的所有窗口,那么下次我导航回我的站点时,将找不到会话 cookie。我在我的 cookie 上设置了 1 年的持续时间/过期时间,所以它不会过期。

到目前为止,我发现的唯一一件事是这是 .NET 4.0 中的一个错误,并且在 .NET 4.5 中已修复。通过查看我的 *.csproj 和 TargetFrameworkVersion 元素,我相信我已经在运行 .NET 4.5:

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>
    </ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>xxxxxxxxxxxxxxxxxx</ProjectGuid>
    <ProjectTypeGuids>xxxxxxxx;xxxxxxxxxxxxx;xxxxxxxxxxxxxxxx</ProjectTypeGuids>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>MyApp</RootNamespace>
    <AssemblyName>MyApp</AssemblyName>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <MvcBuildViews>false</MvcBuildViews>
    <UseIISExpress>true</UseIISExpress>
    <IISExpressSSLPort />
    <IISExpressAnonymousAuthentication />
    <IISExpressWindowsAuthentication />
    <IISExpressUseClassicPipelineMode />
  </PropertyGroup>

这是 .NET(或 MVC)的错误,还是我的编码?我是否需要升级到 MVC 5(而不是原来的建议升级到 .NET 4.5)?

这确实困扰着我,因为接下来几个月访问我网站的大部分流量将来自移动用户,如果他们每次都必须继续登录,我可能会失去其中一些(我知道我讨厌必须在移动设备上登录...)

编辑:

顺便说一句 - 这是同一主题的另一页:Asp.Net Forms Authentication when using iPhone UIWebView

我也尝试过实现它,但也没有用:

http://www.bloggersworld.com/index.php/asp-net-forms-authentication-iphone-cookies/

以上内容包括 Scott Hanselmans 建议的修复:

http://www.hanselman.com/blog/FormsAuthenticationOnASPNETSitesWithTheGoogleChromeBrowserOnIOS.aspx

这是我的 cookie 创建代码,以防有帮助:

private void CreateAndSetAuthenticationCookie(int loginId, string username)
    
        HttpCookie cookie = CreateAuthenticationCookie(loginId, username);

        _cookieService.SetCookie(cookie);
    

    private HttpCookie CreateAuthenticationCookie(int loginId, string username)
    
        string userData = string.Format("loginId:0,username:1", loginId, username);
        var ticket = new FormsAuthenticationTicket(loginId, username, DateTime.Now, DateTime.Now.AddYears(1), false, userData, FormsAuthentication.FormsCookiePath);
        string encryptedTicket = FormsAuthentication.Encrypt(ticket);

        return new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
    

我在我的 cmets 中指出的一件事,我将“PersistentCookie”设置为 false....不确定这是否有影响,我会做更多的研究。

更新:

首先,PersistentCookie 现在设置为 true,并且对行为没有任何改变。

下面的一位评论者建议我在从 iPhone 访问网站时运行 Fiddler。在完成设置的非常简单的步骤之后,这就是我发现的。

我尝试的第一个请求指出(我相信)实际问题是什么。当我检查第一个请求时,iOS Safari 正在发送一个 DNT 标头。不知道那是什么,我查了一下,它是一个“请勿跟踪”标题。

接下来,我检查了我的 Safari 设置以将其关闭。你猜怎么着,已经关了。为什么在未设置设置(设置 -> Safari -> 不跟踪)时,Safari(iOS)会发送 DNT 标头?此外,它正下方的 Block Cookie 设置为“从不”。

在对此感到沮丧之后,我去检查了 Chrome for iOS,看看它是否仍然无法正常工作。有用!据我所知,我会关闭所有选项卡,再试一次,关闭所有选项卡,然后关闭浏览器,它仍然可以工作。万岁!

现在,我需要弄清楚为什么 iOS Safari 会发送 DNT 标头...

【问题讨论】:

哇,两周后,我终于找到了这个:bloggersworld.com/index.php/… 但我太累了,今晚无法尝试……很快就会尝试。 呃,那是不行的……Bueller???? 只是猜测,但您使用 iframe 吗?苹果设备不喜欢第三方 cookie,这可能是个问题。 让我们从一些基本的调试开始...... cookie 是真的消失了,还是它被发送到服务器并且服务器由于某种原因而忽略了?查看 HTTP 流量以准确了解在网络上来回传输的内容。为此使用提琴手。 docs.telerik.com/fiddler/configure-fiddler/tasks/… 如果您按照这些说明进行操作,fiddler 将让您查看手机和互联网之间的所有 HTTP/HTTPS 流量 【参考方案1】:

这太尴尬了。我发现我的 iOS Safari 浏览器多年来一直处于“私人浏览模式”!

我觉得我的“软件开发人员”职位需要删除一段时间。很抱歉浪费了大家的时间。

【讨论】:

为人正直,谦逊有为 可能没有你想的那么尴尬。乍一看有点难说。 发生在每个人身上。如果有人说没有,他们实际上并没有做任何工作。 我在 Express 和 iOS 中设置 cookie 时遇到了同样的问题。在私人模式下,Safari 会为每个新标签清除 cookie!希望它对任何人都有帮助。 我的老板在私人模式下使用 Safari 至少一年了,并抱怨网站无法正常运行...谢谢您的回答!【参考方案2】:

我认为您使用持久 cookie 回答了您自己的问题。常规 cookie 在浏览器会话结束时过期(这通常是关闭浏览器)。持久性 cookie 有一个应该被删除的日期,并且可以跨浏览器会话存在。

您的代码应如下所示:

private HttpCookie CreateAuthenticationCookie(int loginId, string username)

    string userData = string.Format("loginId:0,username:1", loginId, username);
    var ticket = new FormsAuthenticationTicket(loginId, username, 
                         DateTime.Now, DateTime.Now.AddYears(1), 
                         false, userData, FormsAuthentication.FormsCookiePath);
    string encryptedTicket = FormsAuthentication.Encrypt(ticket);

    return new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
         Expires = DateTime.Now.AddYears(1);
    ;

这样,您的 cookie 将在浏览器会话中保留一年。

【讨论】:

我已经尝试过了,(我的评论“不,没关系”)。我可以尝试将所有内容都放在同一个方法中,看看是否会有所不同...(我的版本在一种方法中使用票证,在另一种方法中使用 cookie) 使用诸如 firebug/chrome 开发工具之类的东西,你能向客户端展示你的 cookie 的样子吗? 我赞成这个答案,但不接受,因为这只修复了 iOS Chrome,而不是 Safari。

以上是关于在 iOS Safari 上的浏览​​器会话之间未保存 Cookie的主要内容,如果未能解决你的问题,请参考以下文章

关闭会话时未删除移动浏览器(chrome、safari)cookie

iOS上的safari中未显示电话号码

在 WKWebView 和 Safari 之间共享会话

safari 14.2 中未显示着色器材质

检查 IOS 上的 Facebook Connect 会话

iOS 上的 Safari 浏览器为何比其他浏览器更快?