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)ユーザー情報と「最後の更新」と「ログイン」と呼ばれるフィールドを保持するユーザーログインテーブルを持っています。ユーザーが現在の時刻日に「最後の更新」と「ログイン」を1.でログインすると、ユーザーが再びログインすることができなくなります。
2)jQuery ajaxコールを作成して、新しいタイムデートスタンプでデータベースフィールド「最後の更新」を更新します。これはスケジュールで(1分ごとに)発生します。
3)私がしなければならなかった最後のことは、アクティブログインの最後の更新(データベース内)の最後の更新が一定期間よりも大きいかどうかを確認するためにチェックするタスクをスケジュールすることでした。 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
, 、セッションをに設定します {}
, 、セッションをむき出しのプロパティに設定します {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>