Cookies ColdFusion:会话变量不在网站中,从CF 8迁移到CF 10
我管理一个基于ColdFusion的网站,该网站最近从CF8迁移到了CF10。该站点要求用户登录并在会话变量中保留某些值,这些变量在整个站点中用于验证等 自从迁移到CF 10以来,我一直有很多问题,会话不能在页面之间“粘住”,特别是在登录过程之后。在迁移之前,我没有使用cookies跟踪客户端上的值,也没有对我的Cookies ColdFusion:会话变量不在网站中,从CF 8迁移到CF 10,cookies,coldfusion,session-variables,coldfusion-10,coldfusion-8,Cookies,Coldfusion,Session Variables,Coldfusion 10,Coldfusion 8,我管理一个基于ColdFusion的网站,该网站最近从CF8迁移到了CF10。该站点要求用户登录并在会话变量中保留某些值,这些变量在整个站点中用于验证等 自从迁移到CF 10以来,我一直有很多问题,会话不能在页面之间“粘住”,特别是在登录过程之后。在迁移之前,我没有使用cookies跟踪客户端上的值,也没有对我的cflocation标记使用addtoken=“yes”(我更愿意将CFID和CFTOKEN值保留在URL之外) 我在这方面做了很多研究,但我正在努力寻找解决方案 我尝试设置立即过期的
cflocation
标记使用addtoken=“yes”
(我更愿意将CFID
和CFTOKEN
值保留在URL之外)
我在这方面做了很多研究,但我正在努力寻找解决方案
- 我尝试设置立即过期的“虚拟”cookie(请参阅 ), 但这并不能提供一致的解决方案
- 我也读过
处理CF 9中更改的请求的方式(特别是, 9.0.1;见), 但即使在更改mycflocation
以添加令牌作为 测试中,会话不断重置cflocation
- 如果我包括那一页
在用户以
身份登录后显示,my sessions do 坚持,但一旦我点击到网站上的另一个页面 会话再次重置(我猜这是由于服务器检查cfinclude
再次)Application.cfm
Application.cfm
设置默认会话值吗?我应该在登录页面上这样做吗
作为参考,当前的Application.cfm
如下所示(出于安全目的更改了某些值):
编辑:最后,这里是检查每个用户的include,如果他们未经授权,则将他们踢到超时页面:
<cflock scope="session" type="readonly" timeout="2">
<cfif not structKeyExists(session,"SESSIONVARA")>
<cflocation url="TIMEOUTPAGE" addtoken="no">
</cfif>
</cflock>
Application.cfm中的代码将始终设置默认值,无论以前是否设置过。由于您正在检查会话变量是否存在以确定用户是否登录,因此我建议完全删除Application.cfm中设置/更新会话变量的代码。这样,在登录成功之前,它不会存在 现在,如果应用程序中的其他地方也希望使用这些相同的会话变量,我建议仅当它们不存在时才将其设置为默认值。使用以下代码(无需锁定)最容易做到这一点:
然后更改安全检查以检查这些变量的值,而不是它们是否存在。感谢所有回答此问题的人。我相信我已经解决了我最初的问题。这个拼图有几个部分,我想在这里详细阐述一下,以供将来参考 首先也是最重要的,正如@BradWood所说的,将我的默认会话声明移出
application.cfm
非常有帮助。我基本上是在每一页上重置自己的值。我的application.cfm
现在看起来像这样:
<cfapplication name="SITENAME"
applicationtimeout="#createtimespan(0,6,0,0)#"
clientmanagement="no"
datasource="DATASOURCENAME"
loginstorage="session"
scriptprotect="all"
sessionmanagement="yes"
sessiontimeout="#createtimespan(0,1,0,0)#"
setclientcookies="no">
最后,这里是我的logout.cfm
页面,它清除了仅会话的cookies:
<cfscript>
StructDelete(cookie,"cfid",true);
StructDelete(cookie,"cftoken",true);
</cfscript>
<!--- force cookies to expire --->
<cfcookie name="cfid" domain="#cgi.SERVER_NAME#" expires="now">
<cfcookie name="cftoken" domain="#cgi.SERVER_NAME#" expires="now">
<!--- force session to end --->
<cfset sessionInvalidate() />
<cflocation url="index.cfm" addtoken="no">
StructDelete(cookie,“cfid”,true);
StructDelete(cookie,“cftoken”,true);
到目前为止,所有这些都很好地解决了我的会话问题。我希望所有这些信息都能对其他有类似问题的人有所帮助
更新(7-27-2015):我已经修改了这个额外的解释,包括两行cfcookie命令,这两行命令cookie立即过期。在我发布此信息的一年中,我注意到用户会因为重复的cookie而遇到问题。如果用户在未清除浏览器cookie或完全关闭浏览器的情况下重新登录,则会保留其上一次会话中的cookie。这导致了一个冲突,系统将看到两对同名的cookie并将其混淆。强制将过期日期设置为“现在”有效地消除了旧cookie并恢复了站点的正常状态。您是否尝试过J2EE会话变量。该设置位于coldfusion administrator中。我知道IE存在一个问题,特别是会话变量不稳定,解决方法是使用J2EE会话变量。在Application.cfm和login页面中,structKeyExists的目的是什么,因为不管怎样,您似乎仍在设置值。事实上,Application.cfm中的整个块可以缩短为:session.SESSIONVARA=“DEFAULTVALUE”;session.SESSIONVARB=“DEFAULTVALUE”;因为它总是设置默认值。这似乎有问题。此外,会话范围的大部分锁定可能是不必要的。你能展示加强你安全的代码吗?@BradWood:谢谢你的回复。我开始使用structKeyExists和simple assignments,看看这对会话和cookie变量是否有帮助。我还意识到,在application.cfm中使用默认会话声明实际上是在用户每次访问新页面时重置变量,因此我将这些变量移动到login.cfm中,以便它们只在那里声明。会话无效,我的注销页面上的Cookie被清除。至于“加强我的安全性”,你的意思是什么代码会驱逐未经授权的用户?@AlanBullpitt我在阅读的一些文章中看到了对J2EE会话变量的引用,但不确定如何使用它们。我个人没有访问CFAdmin的权限,但我会询问我们的服务器技术人员。谢谢。是的,我指的是驱逐用户的代码。那么,移动默认值是否解决了问题?在Application.cfm中应该没有理由不能这样做,但是只需要if语句的一半——它们尚未定义的那一半。如果这是个问题,我会把它写在一个答案里,这样你就可以接受了。非常感谢,
<cfparam name="session.sessionvara" default="defaultvalue">
<cfparam name="session.sessionvarb" default="defaultvalue">
<cfapplication name="SITENAME"
applicationtimeout="#createtimespan(0,6,0,0)#"
clientmanagement="no"
datasource="DATASOURCENAME"
loginstorage="session"
scriptprotect="all"
sessionmanagement="yes"
sessiontimeout="#createtimespan(0,1,0,0)#"
setclientcookies="no">
<!--- check whether this variable was passed to this page --->
<cfif isdefined("form.username") and form.username is not "">
<!--- generate a hashed password from the user's entry --->
<cfset HashedPassword = hash(form.Password,"SHA-1")>
[ SQL QUERY TO CHECK USER'S CREDENTIALS ]
<cfif SQLQUERY.RecordCount is not 0>
<cfset sessionRotate()>
<cflock scope="session" type="exclusive" timeout="5">
<!--- check to see if a user session has been started by looking for one of the variables --->
<cfif structKeyExists(session,"SESSIONVARA")>
<cfscript>
StructUpdate(session,"SESSIONVARA",VALUEA);
StructUpdate(session,"SESSIONVARB",VALUEB);
StructUpdate(session,"SESSIONVARC",VALUEC);
StructUpdate(session,"SESSIONVARD",VALUED);
StructUpdate(session,"SESSIONVARE",VALUEE);
</cfscript>
<cfelse>
<cfscript>
StructInsert(session,"SESSIONVARA",VALUEA);
StructInsert(session,"SESSIONVARB",VALUEB);
StructInsert(session,"SESSIONVARC",VALUEC);
StructInsert(session,"SESSIONVARD",VALUED);
StructInsert(session,"SESSIONVARE",VALUEE);
</cfscript>
</cfif>
</cflock>
<!--- Set session-only cookies to help the site remember credentials.
Don't set an expire value in order to prevent CF from creating client cookies.
If a cookie already exists, let's use that one and update the CFID and CFTOKEN
values to match the new session set in sessionRotate(). Also, don't declare the
"path" attribute in cfcookie: it will create a duplicate set of cookies and
confuse the site as to which is the right one. --->
<cfif structKeyExists(cookie,"cfid")>
<cfset cookie.cfid = session.cfid>
<cfset cookie.cftoken = session.cftoken>
<cfelse>
<cfcookie name="cfid" value="#session.cfid#" domain="#cgi.SERVER_NAME#">
<cfcookie name="cftoken" value="#session.cftoken#" domain="#cgi.SERVER_NAME#">
</cfif>
<cflocation url="main.cfm" addtoken="no">
<cfelse>
<cflocation url="login-failed.cfm" addtoken="no">
</cfif>
<!--- if there is no user name defined in the set of form variables, this is probably a spider or bot; reject it --->
<cfelse>
<cflocation url="index.cfm" addtoken="no">
</cfif>
<cfscript>
StructDelete(cookie,"cfid",true);
StructDelete(cookie,"cftoken",true);
</cfscript>
<!--- force cookies to expire --->
<cfcookie name="cfid" domain="#cgi.SERVER_NAME#" expires="now">
<cfcookie name="cftoken" domain="#cgi.SERVER_NAME#" expires="now">
<!--- force session to end --->
<cfset sessionInvalidate() />
<cflocation url="index.cfm" addtoken="no">