ColdFusion:会话变量不在网站从CF 8迁移到CF 10 [英] ColdFusion: session variables not sticking in website migrated from CF 8 to CF 10
问题描述
我管理最近从CF 8迁移到CF 10的基于ColdFusion的网站。该网站要求用户登录并在会话变量中保留某些值,这些值在整个网站中用于验证等。
自从迁移到CF 10后,我一直在使用会话而不是粘贴一个页面到页面,特别是在登录过程之后,有很多麻烦。我没有使用cookie来跟踪客户端上的值,在迁移之前,我也不使用 addtoken =yes
为我的 cflocation
标签(我想保留 CFID
和 CFTOKEN
URL)。
我一直在做很多研究,但是一直在努力的解决方案。
- 我已经尝试设置dummycookie,它立即过期(参见
Lose session in Coldfusion ),
,但这不能提供一致的解决方案。 - 我也读过
的方式cflocation
处理在CF 9中更改的请求(具体来说,
9.0.1;请参阅 http://www.horisk.com/blog/index.cfm / $ / $ / $ / $ / $ / $ / $ / $ / $ / $ / $ / $ / $ / $ / $ / / code>添加令牌作为
测试的一部分,会话将继续重置。 - 如果我包括用户日志后出现
的页面作为一个cfinclude
,我的会话做
棒,但一旦我点击离开到网站上的另一个页面,
会话重新再次我的猜测是由于服务器再次检查
Application.cfm
。
我做错了什么或缺少什么?我应该没有 Application.cfm
设置默认会话值吗?
作为参考,当前 Application.cfm
的内容如下为了安全起见):
< cfapplication name =APPLICATIONNAME
applicationtimeout =#createtimespan 6,0,0)#
clientmanagement =yes
datasource =DATASOURCENAME
loginstorage =session
scriptprotect =all
sessionmanagement = yes
sessiontimeout =#createtimespan(0,1,0,0)#
setclientcookies =yes>
< cfif不structKeyExists(cookie,cfid)>
< cfcookie name =cfidvalue =#session.cfid#expires =neverdomain =#cgi.SERVER_NAME#path =/ PATH>
< cfcookie name =cftokenvalue =#session.cftoken#expires =neverdomain =#cgi.SERVER_NAME#path =/ PATH>
< / cfif>
< cflock timeout =5throwontimeout =notype =exclusivescope =session>
< cfif structKeyExists(session,SESSIONVARA)>
< cfscript> StructUpdate(session,SESSIONVARA,DEFAULTVALUE);< / cfscript>
< cfelse>
< cfscript> StructInsert(session,SESSIONVARA,DEFAULTVALUE);< / cfscript>
< / cfif>
< cfif structKeyExists(session,SESSIONVARB)>
< cfscript> StructUpdate(session,SESSIONVARB,DEFAULTVALUE);< / cfscript>
< cfelse>
< cfscript> StructInsert(session,SESSIONVARB,DEFAULTVALUE);< / cfscript>
< / cfif>
。 。 。
< / cflock>
我目前的 login.cfm
(再次更改某些值):
<!---检查此变量是否已传递到此页面 - - >
< cfif isdefined(form.username)和form.username不是>
<!---从用户输入生成一个哈希密码--->
< cfset HashedPassword = hash(form.Password,SHA-1)>
[查询用户凭据的SQL查询]
< cfif SQLQUERY.RecordCount不是0>
< cfset sessionRotate()>
< cflock scope =sessiontype =exclusivetimeout =2>
< cfset session.SESSIONVARA = QUERYVALUEA>
< cfset session.SESSIONVARB = QUERYVALUEB>
。 。 。
< / cflock>
<!--- put after sessionRotate()保持ID一致--->
< cfif structKeyExists(cookie,cfid)>
< cfset cookie.cfid = session.cfid>
< cfset cookie.cftoken = session.cftoken>
< cfelse>
< cfcookie name =cfidvalue =#session.cfid#expires =neverdomain =#cgi.SERVER_NAME#path =/ PATH>
< cfcookie name =cftokenvalue =#session.cftoken#expires =neverdomain =#cgi.SERVER_NAME#path =/ PATH>
< / cfif>
< cflocation url =main.cfmaddtoken =no>
< cfelse>
<!---无匹配凭据--->
< cflocation url =login-failed.cfmaddtoken =no>
< / cfif>
<!---如果在表单变量集中没有定义用户名,这可能是一个蜘蛛或bot;拒绝它--->
< cfelse>
< cflocation url =index.cfmaddtoken =no>
< / cfif>
编辑:最后,如果未授权,则将它们踢到超时页面:
< cflock scope =sessiontype =readonly timeout =2>
< cfif not structKeyExists(session,SESSIONVARA)>
< cflocation url =TIMEOUTPAGEaddtoken =no>
< / cfif>
< / cflock>
Application.cfm中的代码将始终设置默认值,而不管它是否以前设置。因为您正在检查会话变量的存在以确定用户是否登录,我建议完全删除Application.cfm中设置/更新会话变量的代码。
现在,如果应用程序中的其他地方也想使用这些相同的会话变量,我会建议设置设置为默认值(如果它们不存在)。这是最容易用以下代码完成(不需要锁定):
< cfparam name =session.sessionvaradefault =defaultvalue>
< cfparam name =session.sessionvarbdefault =defaultvalue>
然后更改安全检查以检查这些变量的值,而不是它们是否存在。 / p>
I manage a ColdFusion-based website that recently migrated from CF 8 to CF 10. The site requires users to log in and keeps certain values in session variables, which are used throughout the site for verification, etc.
Since the migration to CF 10, I have been having a lot of trouble with sessions not "sticking" from page to page, particularly after the login process. I had not been using cookies to keep track of values on the client side prior to the migration, nor do I use addtoken="yes"
for my cflocation
tags (I'd prefer to keep the CFID
and CFTOKEN
values out of the URL).
I've been doing a lot of research on this, but am struggling with a solution.
- I've tried setting "dummy" cookies that expire immediately (see Losing session in Coldfusion), but this does not offer a consistent solution.
- I've also read that
the way
cflocation
handles requests changed in CF 9 (specifically, 9.0.1; see http://www.horisk.com/blog/index.cfm/2011/5/19/Session-issues-after-installing-Coldfusion-901-update--OnRequestEnd-behaviour-change), but even after changing mycflocation
to add tokens as part of testing, the sessions keep getting reset. - If I include the page that
appears after the user logs in as a
cfinclude
, my sessions do stick, but as soon as I click away to another page on the site, the sessions reset again (my guess is it's due to the server checkingApplication.cfm
again).
What I am doing wrong or missing? Should I not have Application.cfm
set default session values? Should I do this on the login page?
For reference, current Application.cfm
reads as follows (certain values changed for security purposes):
<cfapplication name="APPLICATIONNAME"
applicationtimeout="#createtimespan(0,6,0,0)#"
clientmanagement="yes"
datasource="DATASOURCENAME"
loginstorage="session"
scriptprotect="all"
sessionmanagement="yes"
sessiontimeout="#createtimespan(0,1,0,0)#"
setclientcookies="yes">
<cfif not structKeyExists(cookie,"cfid")>
<cfcookie name="cfid" value="#session.cfid#" expires="never" domain="#cgi.SERVER_NAME#" path="/PATH">
<cfcookie name="cftoken" value="#session.cftoken#" expires="never" domain="#cgi.SERVER_NAME#" path="/PATH">
</cfif>
<cflock timeout="5" throwontimeout="no" type="exclusive" scope="session">
<cfif structKeyExists(session,"SESSIONVARA")>
<cfscript>StructUpdate(session,"SESSIONVARA","DEFAULTVALUE");</cfscript>
<cfelse>
<cfscript>StructInsert(session,"SESSIONVARA","DEFAULTVALUE");</cfscript>
</cfif>
<cfif structKeyExists(session,"SESSIONVARB")>
<cfscript>StructUpdate(session,"SESSIONVARB","DEFAULTVALUE");</cfscript>
<cfelse>
<cfscript>StructInsert(session,"SESSIONVARB","DEFAULTVALUE");</cfscript>
</cfif>
. . .
</cflock>
My current login.cfm
page reads as follows (again, certain values changed):
<!--- 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="2">
<cfset session.SESSIONVARA = QUERYVALUEA>
<cfset session.SESSIONVARB = QUERYVALUEB>
. . .
</cflock>
<!--- put after sessionRotate() to keep IDs consistent --->
<cfif structKeyExists(cookie,"cfid")>
<cfset cookie.cfid = session.cfid>
<cfset cookie.cftoken = session.cftoken>
<cfelse>
<cfcookie name="cfid" value="#session.cfid#" expires="never" domain="#cgi.SERVER_NAME#" path="/PATH">
<cfcookie name="cftoken" value="#session.cftoken#" expires="never" domain="#cgi.SERVER_NAME#" path="/PATH">
</cfif>
<cflocation url="main.cfm" addtoken="no">
<cfelse>
<!--- no matching credentials --->
<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>
Edit: And, lastly, here is the include that checks each user and kicks them to a timeout page if they are not authorized:
<cflock scope="session" type="readonly" timeout="2">
<cfif not structKeyExists(session,"SESSIONVARA")>
<cflocation url="TIMEOUTPAGE" addtoken="no">
</cfif>
</cflock>
Your code in Application.cfm will always set the default value regardless of whether it was previously set. Since you are checking for the existence of the session variable to determine if the user is logged in, I would recommend completely removing the code in Application.cfm that sets/updates the session variables. That way, it won't exist until the login is successful.
Now, if other places in your application also want to use those same session variables, I would recommend setting to a default value only if they don't exist. This is most easily done with the following code (no locking required):
<cfparam name="session.sessionvara" default="defaultvalue">
<cfparam name="session.sessionvarb" default="defaultvalue">
Then change your security check to inspect the value of those variables instead of whether or not they exist.
这篇关于ColdFusion:会话变量不在网站从CF 8迁移到CF 10的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!