在 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的主要内容,如果未能解决你的问题,请参考以下文章