【发布时间】:2018-03-19 19:20:35
【问题描述】:
我想知道如何以及在 X 次登录失败后锁定用户帐户的最佳方法是什么?我有一个表,我可以在其中跟踪用户失败的登录尝试。表存储时间戳、用户名、IP 地址和浏览器类型。在我检测到不正确的登录信息后,cfquery 将根据用户名或 IP 地址从失败的登录表中提取记录。如果有 5 次或更多无效尝试,我将帐户设置为不活动。现在我想以某种方式设置计时器,该计时器将在该用户上次无效尝试后开始计数 5 分钟。然后帐户应将状态更改为活动。这是我到目前为止的代码:
<cfquery name="checkUser" datasource="#dsn#">
SELECT UserName, Password, Salt, LockedUntil
FROM Users
WHERE UserName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(FORM.username)#" maxlength="50">
AND Active = 1
</cfquery>
<cfif len(checkUser.LockedUntil) AND dateCompare(now(), checkUser.LockedUntil,'n') EQ -1>
<cfset fnResults.status = "400">
<cfset fnResults.message = "This account is locked for 5 min.">
<cfreturn fnResults>
<cfabort>
</cfif>
<cfset storedPW = checkUser.Password>
<cfset enteredPW = FORM.password & checkUser.Salt>
<cfif checkUser.recordCount NEQ '1' OR (hash(enteredPW,"SHA-512") NEQ storedPW>
<cfquery name="logFail" datasource="#dsn#">
INSERT INTO FailedLogins(
LoginTime,
LoginUN,
LoginIP,
LoginBrowser
)VALUES(
CURRENT_TIMESTAMP,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#FORM.username#" maxlength="50">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#REMOTE_ADDR#" maxlength="20">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#CGI.HTTP_USER_AGENT#" maxlength="500">
)
</cfquery>
<!--- Pull failed logins based on username or IP address. --->
<cfquery name="failedAttempts" datasource="#dsn#">
SELECT LoginTime
FROM FailedLogins
WHERE LoginUN = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(FORM.username)#" maxlength="50">
OR LoginIP = <cfqueryparam cfsqltype="cf_sql_varchar" value="#REMOTE_ADDR#" maxlength="20">
</cfquery>
<cfif failedAttempts.recordcount LT 4>
<cfset fnResults.status = "400">
<cfset fnResults.message = "Invalid Username or Password!">
<cfelseif failedAttempts.recordcount EQ 4>
<cfset fnResults.status = "400">
<cfset fnResults.message = "This is your last attempt. If you fail to provide correct information account will be locked!">
<cfelseif failedAttempts.recordcount GTE 5>
<cfset lockUntil = DateAdd('n', 5, now())>
<cfquery name="blockUser" datasource="#dsn#">
UPDATE Users
SET LockedUntil = <cfqueryparam cfsqltype="cf_sql_timestamp" value="#lockUntil#">
WHERE UserName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(FORM.username)#" maxlength="50">
</cfquery>
<cfset fnResults.status = "400">
<cfset fnResults.message = "This account is locked for 5 min.">
</cfif>
<cfelse>
//Clear failed login attempts
//Update lockedUntil field to NULL
//User logged in authentication successful!
</cfif>
帐户设置为非活动/锁定后,设置倒计时和更改标志状态的最佳方法是什么?我看到有人推荐 SQL Job,但我不确定作业应该多久运行一次以及如何创建该语句?如果有人可以提供一些例子,请告诉我。谢谢你。
【问题讨论】:
-
推荐的 SQL 作业,但我不确定...如何创建该语句请不要采取错误的方式,但您是否查看过您的 dbms 文档并实际尝试了这些例子?搜索“sql server 计划作业”会返回大量结果和示例。 stackoverflow.com/questions/5471080/….
-
@Ageax 我已经检查过了,是的,有很多示例,但对于我必须在特定时间段内锁定记录的这种特殊情况却没有。另外我不确定这是否是最有效的方法,因为 SQL 作业应该一直在运行,并不断检查失败的尝试记录。
-
不要创建计划作业。这不是必需的,因此会给您的数据库添加不需要的处理。看看@David-Faber 提供的答案。只需在您的查询中添加一个额外的检查,以查看当前的登录尝试是否超出了锁定期。
-
@Shawn 或者您在/如果成功登录尝试时进行清理。
-
我的意思是,在用户成功输入登录凭据(而不是计划的作业)后清理数据库。仅适用于该用户。没关系,无论哪种方式都可以。
标签: sql sql-server-2008 coldfusion locking unlock