Empêcher les connexions de ColdFusion
-
28-09-2019 - |
Question
Quelle est la meilleure façon d'empêcher les connexions multiples en 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>
La solution
Là où je travaille, ils ont des exigences strictes de limiter le nombre de connexions par un seul utilisateur à une seule application. Je me suis approché ce problème cela comme ceci:
1) Avoir une table de connexion de l'utilisateur qui détient les informations d'utilisateur et un champ qui a appelé « la dernière mise à jour » et « Connecté ». Lorsque l'utilisateur se connecte à la « dernière mise à jour » avec la date de l'heure actuelle et les « connectés » avec un 1. Cela empêche l'utilisateur de se connecter à nouveau.
2) Créer un appel ajax jquery de mettre à jour le champ de base de données « dernière mise à jour » avec un nouveau timbre à date du temps. Cela se produit sur un programme (comme tous les 1 min).
3) La dernière chose que je devais faire était planifier une tâche qui vérifié pour voir si la dernière mise à jour pour les connexions actives (dans la base de données) était supérieure à une période de temps déterminée, si elle était que les utilisateurs « Connecté » statut était changé de 1 à 0 (ce qui leur permet de se connecter à nouveau). La raison pour laquelle cela est important est que vous ne pouvez pas supposer que l'utilisateur sera toujours cliquer sur « déconnexion » quand ils partent. Parfois, ils fermer leur navigateur ou loin naviguer. Lorsque cela se produit s'ils ont tenté de revenir à l'application, ils ne seraient pas en mesure de se connecter à nouveau (parce que la base de données pense qu'ils sont déjà connectés).
Espérons que cela vous arrive d'aller dans la bonne direction.
Autres conseils
La meilleure façon que je trouve à faire est de lier dans le cadre de la session java sous-jacente dans ColdFusion et recherchez un login existant pour celui que vous avez.
Si elle est là, sur le coup / expire l'autre session et laisser l'actuel dans.
Voici un exemple de mon code. Prenez note qu'il existe différentes façons de tuer / mettre fin à une session chacun avec leurs propres avantages / inconvénients. Cet exemple est une base de code hérité.
getLogin.fld_userid est ce que l'ID de connexion est une tentative de la forme html.
J'ai ce code execute pendant « lors de la connexion » avant que j'initialiser les variables de session.
<!---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>
Basé sur Jas'z Réponse :
Je suppose de leur réponse que les techniques ne sont pas parvenus commentaires ce qu'ils désiraient à l'époque (2010).
Par googling, la méthode de la session (de la java sous-jacent) setMaxInactiveInterval
peut ne plus fonctionner (tel qu'il apparaît à l'aide Lucee 5 et base de données MySQL pour le stockage de session)
J'ai essayé beaucoup de choses à éclaircir la session, comme structClear
, le réglage de la session {}
, le réglage de la session, les propriétés nues {cfid, cftoken...}
, et aucune de ces travaillé.
La seule chose qui a fait le travail a été ou la modification des propriétés couchait individuelles de la session, comme thisSession.loggedIn
.
utilisations pour cela pourrait inclure permettant aux utilisateurs de voir et de contrôle où sinon ils sont connectés.
<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>