2

防止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>
4

3 回答 3

1

在我工作的地方,他们对限制单个用户对单个应用程序的登录次数有严格的要求。我这样处理这个问题:

1)有一个用户登录表,其中包含用户信息和一个名为“上次更新”和“登录”的字段。当用户使用当前时间日期登录“上次更新”并且使用 1 登录“登录”时。这可以防止该用户再次登录。

2) 创建一个 jquery ajax 调用以使用新的时间戳更新数据库字段“上次更新”。这按计划进行(例如每 1 分钟)。

3)我要做的最后一件事是安排一个任务,检查活动登录(在数据库中)的最后更新是否大于固定时间段,如果是用户“登录”状态从 1 更改为 0(允许他们再次登录)。这很重要的原因是您不能假设用户在离开时总是会单击“注销”。有时他们只是关闭浏览器或导航离开。当这种情况发生时,如果他们试图返回应用程序,他们将无法再次登录(因为数据库认为他们已经登录)。

希望这能让你朝着正确的方向前进。

于 2010-11-03T13:56:08.073 回答
1

我发现做到这一点的最简单方法是绑定到 ColdFusion 中的底层 Java 会话范围,并为您拥有的那个查找现有的登录名。

如果它在那里,踢出/终止另一个会话并让当前会话进入。

这是我的代码中的一个示例。请注意,有不同的方法可以杀死/结束会话,每种方法都有自己的优点/缺点。此示例适用于继承的代码库。

getLogin.fld_userid 是来自 html 表单的尝试登录 ID。

在初始化会话变量之前,我在“登录时”期间运行了这段代码。

<!---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>
于 2010-11-03T15:58:07.343 回答
0

基于Jas'z 答案

我会从他们的回答中假设评论的技术没有达到他们当时(2010)的期望。

根据一些谷歌搜索,会话方法(来自底层 java)setMaxInactiveInterval可能不再起作用(因为它使用 Lucee 5 和 MySQL 数据库进行会话存储)

我尝试了很多方法来清除会话,例如structClear,将会话{}设置为 ,将会话设置为裸属性{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>
于 2019-09-07T13:23:48.750 回答