防止同时登录ColdFusion
-
28-09-2019 - |
题
什么是防止CF多次登录的最简单方法?
<cfcomponent>
<cfset This.name = "Name">
<cfset This.Sessionmanagement="True">
<cfset This.loginstorage="session">
<cfset This.sessionTimeout = "#CreateTimeSpan(0, 0, 50, 0)#">
<cfset This.applicationtimeout="#createtimespan(0,0,50,0)#">
<cfset This.scriptProtect = "All">
<cffunction name="OnRequestStart">
<cfargument name = "request" required="true"/>
<cfif IsDefined("Form.logout")>
<cflogout>
<cfset StructClear(Session)>
<cflocation url="/" addtoken="no">
</cfif>
<cflogin>
<cfif NOT IsDefined("cflogin")>
<cfinclude template="loginform.cfm">
<cfabort>
<cfelse>
<cfif cflogin.name IS "" OR cflogin.password IS "">
<cfoutput>
You must enter text in both the User Name and Password fields.
</cfoutput>
<cfinclude template="loginform.cfm">
<cfabort>
<cfelse>
<cfquery name="loginQuery" dataSource="datadsn">
SELECT *
FROM userlogin
WHERE
UserID = <cfqueryparam value="#cflogin.name#" cfsqltype="CF_SQL_VARCHAR">
AND Password = <cfqueryparam value="#hash(cflogin.password)#" cfsqltype="CF_SQL_VARCHAR">
AND trenabled = <cfqueryparam value="1" cfsqltype="CF_SQL_VARCHAR">
<!--- Project ID--->
AND projectid = <cfqueryparam value="23" cfsqltype="CF_SQL_VARCHAR">
</cfquery>
<cfset loginpass = #hash(cflogin.password)#>
<cfset comparison = Compare(loginQuery.Password, loginpass)>
<cfif loginQuery.trRoles NEQ "" AND comparison EQ 0>
<cfloginuser name="#cflogin.name#" Password = "#loginpass#" roles="#loginQuery.trRoles#">
<cfelse>
<cfoutput>
Your login information is not valid.<br>
Please Try again.
</cfoutput>
<cfinclude template="loginform.cfm">
<cfabort>
</cfif>
</cfif>
</cfif>
</cflogin>
<cfif GetAuthUser() NEQ "">
<cfoutput>
<form method="Post">
<input type="submit" Name="Logout" value="Logout">
</form>
</cfoutput>
</cfif>
</cffunction>
<cffunction name="onSessionEnd" returnType="void">
</cffunction>
</cfcomponent>
解决方案
在我工作的地方,他们对将单个用户的登录数量限制为单个应用程序有严格的要求。我解决了这样的问题:
1)拥有一个用户登录表,该表保存用户信息和一个称为“最后更新”和“登录”的字段。当用户在“最后更新”中以当前时间日期登录并使用A 1登录。这会防止用户再次登录。
2)创建一个jQuery ajax调用,以使用新的时间日期邮票更新数据库字段“最后更新”。这是按计划发生的(就像每1分钟一样)。
3)我要做的最后一件事是安排一项任务检查,以查看活动登录的最后更新(数据库中)是否大于固定的时间,如果是用户“登录”状态从1更改为1到0(允许他们再次登录)。之所以如此重要的原因是,您不能假设用户离开时会始终单击“注销”。有时他们只是关闭浏览器或导航。如果他们试图返回应用程序,就会发生这种情况时,他们将无法再次登录(因为数据库认为他们已经登录了)。
希望这能让您朝着正确的方向前进。
其他提示
我发现这样做的最简单方法是将ColdFusion的基础Java会话范围绑定在一起,并为您拥有的现有登录。
如果在那里,请踢出/到期另一个会议,然后让当前的会议进入。
这是我的代码中的一个示例。请注意,每次都有自己的优点/缺点杀死/结束会话的方法有多种方法。此示例是针对继承的代码库。
getLogin.fld_userid是尝试登录ID来自HTML表单的内容。
在初始化会话变量之前,我在“登录”期间运行此代码。
<!---code for 1user per login --->
<cfset liveSessions = createObject("java","coldfusion.runtime.SessionTracker")>
<cfset activesessions = liveSessions.getSessionCollection(YOUR_DATA_SOURCE_NAME)>
<cfloop item="loopSession" collection="#activesessions#">
<cfscript>
thisSession = activesessions[loopSession];
if(StructIsEmpty(thisSession)) {
// do nothing
} else {
if(isDefined("thisSession.loginUserid")) {
thisUser = thisSession.loginuserid;
if(thisSession.loginuserid EQ getlogin.fldUser_ID) {
thisSession.XXAutoToken="";
//structClear(thisSession);
//cflocation(theUrl:"index.cfm?home.welcome");
thisSession.setMaxInactiveInterval(1);
break;
}
}
}
</cfscript>
</cfloop>
基于 jas'z答案:
我从他们的回答中假设,评论的技术并没有达到当时(2010年)的期望。
根据一些谷歌搜索,会话方法(来自基础Java) setMaxInactiveInterval
可能不再起作用(因为使用Lucee 5和MySQL数据库以进行会话存储出现)
我尝试了很多事情来清除会议,例如 structClear
, ,将会话设置为 {}
, ,将会话设置为Bare属性 {cfid, cftoken...}
, ,这些都没有用。
唯一工作的是设置或更改会话的个人属性,例如 thisSession.loggedIn
.
此用途可能包括允许用户查看和控制其他登录位置。
<cfscript>
liveSessions = createObject("java","coldfusion.runtime.SessionTracker");
activeSessions = liveSessions.getSessionCollection(application.applicationName);
for (s in activeSessions) {
thisSession = activeSessions[s];
if (!StructIsEmpty(thisSession)) {
// Change loggedIn to whatever property identifies a login.
if (isDefined("thisSession.loggedIn") && thisSession.loggedIn &&
thisSession.UserID == form.UserID) {
// Change the UserID line above to whatever match you're looking for
if(thisSession.UserID == form.UserID) {
// Change loggedIn to whatever property identifies a login.
lock scope="session" timeout="5" {
thisSession.loggedIn = 0;
}
break;
}
}
}
}
</cfscript>