【发布时间】:2011-01-10 19:25:53
【问题描述】:
无法从 Flash 电影中访问 HTTP cookie,但我现在反复读到 Flash Player 应该自动处理会话 cookie。但是,我找不到任何关于此的文档,而且它肯定不适用于使用默认 JSESSIONID cookie 针对 Struts 后端运行的 Flex 客户端。
那么,Flash Player 是否处理会话 cookie,如果可以,我该如何设置?
【问题讨论】:
无法从 Flash 电影中访问 HTTP cookie,但我现在反复读到 Flash Player 应该自动处理会话 cookie。但是,我找不到任何关于此的文档,而且它肯定不适用于使用默认 JSESSIONID cookie 针对 Struts 后端运行的 Flex 客户端。
那么,Flash Player 是否处理会话 cookie,如果可以,我该如何设置?
【问题讨论】:
来自 Flash 的 HTTP 请求是通过浏览器发送的 - 所以是的,cookie 是自动传输的。事实上,我目前正在做一个在 HTML 页面中处理登录(并因此设置会话 cookie)然后将用户转发到仅 Flash 页面()的站点。 Flash 页面使用 URLLoader 和 URLRequest 向服务器发送大量请求,我能够验证每个请求的会话 cookie。
也就是说,您可以使用 ExternalInterface.call() 从 Flash 访问 HTTP cookie。确保将 SWF 嵌入代码中的 allowScriptAccess 设置为适当的值。
var cookies:String = ExternalInterface.call("function()
{
return document.cookie;
}()");
更新:我没有尝试过(在 Flash 中登录),但您可能是对的 - Flash 可能会忽略 Set-Cookie(或所有)响应标头。不幸的是,Flash 也不允许我们访问响应标头。但是由于可以访问 AJAX 响应中的响应标头(使用 xhr.getResponseHeader),您可以使用 ExternalInterface 并将登录部分 外包 AJAX。获取 AJAX 响应中的标头并使用 javascript 设置 cookie(根据this SO thread,浏览器会自动执行此操作)。设置后,从 flash 发送的后续请求将在其中包含会话 cookie。
使用 ExternalInterface.addCallback 方法注册一个可从 javascript 调用的 flash 方法。
【讨论】:
Flash Player 通常通过浏览器进行联网,在这种情况下设置和获取 cookie 完全由浏览器处理。
如果网站发送 Set-Cookie,应该可以。
您无法从 Flash 内容中访问响应标头,就像您无法从 JavaScript 中访问它们一样;之所以会这样,有根本的安全原因。但是,有一天 Flash Player 可能会允许您通过 cookie API 读取 cookie,就像 JavaScript 一样。同时,ExternalInterface 可以让你调用 JS 来读取 cookie。
在一种情况下,Flash Player 不发送 cookie,甚至可能发送错误的 cookie。那是您使用 FileReference.upload() 的时候。这是一个已知的 Flash Player 错误,但由于 NPAPI 依赖性,Adobe 很难解决。
顺便说一句,此时 JSESSIONID 被认为是不安全的。它很容易受到 CSRF 攻击,因为浏览器会盲目地发送它,无论是谁的文档发出请求。大多数现代登录系统都使用隐藏的表单字段或其他方式来保持登录 nonce 只能由您域内的页面访问。
希望我能告诉您为什么您的特定应用不发送 cookie。您是否尝试过将其与全 HTML 版本进行比较?您是否使用数据包嗅探器监视了两个网络流?
【讨论】:
这个问题是 10 年前提出的,但在这方面我有话要对未来的读者说。
Flash Player 不会在请求中传输默认的 JSESSIONID,并且在您在 JSESSIONID cookie 中设置 SameSite=None 之前无法传输。
我遇到了将 JSESSIONID cookie 丢弃在请求中的问题,我发现这是因为现代浏览器(chrome > 80)不允许 Flash Player 访问 JSESSIONID cookie,因为 cookie 没有 SameSite=None 和 Secure 闪烁。
请阅读 Adobe here 的公告 详细了解新的 cookie 政策:
【讨论】:
我确定这个线程现在已经死了,但我最近在使用 ASP.NET 和 FileUpload 时遇到了类似的问题,并根据here 的一些工作找到了解决方法。
我构建了一个将 Flex 对象动态写入页面的组件,以便它们可以在 UpdatePanel 中使用。如果您想要他们的代码,请给我留言。为了解决需要通过 URLRequest 发送身份验证 cookie 的页面中的上述问题,我将值添加为 flashVars。
此代码仅适用于我的对象,但你明白了
Dictionary<string, string> flashVars = new Dictionary<string, string>();
flashVars.Add("auth", Request.Cookies["LOOKINGGLASSFORMSAUTH"].Value);
flashVars.Add("sess", Request.Cookies["ASP.NET_SessionId"].Value);
myFlexObject.SetFlashVars(flashVars);
然后在 Flex 对象中,检查参数
if (Application.application.parameters.sess != null)
sendVars.sess= Application.application.parameters.sess;
if (Application.application.parameters.auth != null)
sendVars.au= Application.application.parameters.auth;
request.data = sendVars;
request.url = url;
request.method = URLRequestMethod.POST;
最后将 cookie 填入 global.asax BeginRequest
if (Request.RequestType=="POST" && Request.Path.EndsWith("upload.aspx"))
{
try
{
string session_param_name = "sess";
string session_cookie_name = "ASP.NET_SESSIONID";
string session_value = Request.Form[session_param_name]; // ?? Request.QueryString[session_param_name];
if (session_value != null) { UpdateCookie(session_cookie_name, session_value); }
}
catch (Exception) { }
try
{
string auth_param_name = "au";
string auth_cookie_name = FormsAuthentication.FormsCookieName;
string auth_value = Request.Form[auth_param_name];// ?? Request.QueryString[auth_param_name];
if (auth_value != null) { UpdateCookie(auth_cookie_name, auth_value); }
}
catch (Exception) { }
}
希望这可以帮助某人避免我刚刚花费 6 个小时来解决这个问题。 Adobe 已将该问题视为无法解决,因此这是我最后的手段。
【讨论】: