Sql 如何在一段时间内锁定用户帐户?
我想知道在X次登录失败后,如何以及什么是锁定用户帐户的最佳方法?我有一个表,用于跟踪用户失败的登录尝试。表存储时间戳、用户名、ip地址和浏览器类型。在我检测到不正确的登录信息后,cfquery将根据用户名或IP地址从失败的登录表中提取记录。如果有5次或更多无效尝试,我将帐户设置为不活动。现在,我想以某种方式设置计时器,该计时器将从该用户上次无效尝试开始计时5分钟。然后,帐户应将状态更改为“活动”。以下是我目前掌握的代码:Sql 如何在一段时间内锁定用户帐户?,sql,sql-server-2008,coldfusion,locking,unlock,Sql,Sql Server 2008,Coldfusion,Locking,Unlock,我想知道在X次登录失败后,如何以及什么是锁定用户帐户的最佳方法?我有一个表,用于跟踪用户失败的登录尝试。表存储时间戳、用户名、ip地址和浏览器类型。在我检测到不正确的登录信息后,cfquery将根据用户名或IP地址从失败的登录表中提取记录。如果有5次或更多无效尝试,我将帐户设置为不活动。现在,我想以某种方式设置计时器,该计时器将从该用户上次无效尝试开始计时5分钟。然后,帐户应将状态更改为“活动”。以下是我目前掌握的代码: <cfquery name="checkUser" datasour
<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>
选择用户名、密码、Salt、锁定直至
来自用户
其中用户名=
和活动=1
插入失败的登录(
登录时间,
罗吉农,
罗吉尼普,
登录浏览器
)价值观(
当前时间戳,
,
,
)
选择登录时间
来自失败的登录
其中LoginUN=
或LoginIP=
更新用户
设置锁定直到=
其中用户名=
//清除失败的登录尝试
//将lockedUntil字段更新为NULL
//用户登录验证成功!
帐户设置为非活动/锁定后,设置时间倒计时和更改标志状态的最佳方法是什么?我看到一些人推荐SQL作业,但我不确定作业应该多长时间运行一次,以及如何创建该语句?如果有人能提供一些例子,请让我知道。多谢各位 您可以做的是在
checkUser
查询中添加一个条件:
<cfquery name="checkUser" datasource="#dsn#">
SELECT UserName, Password, Salt, Active
FROM Users u
WHERE UserName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(FORM.username)#" maxlength="50">
-- AND Active = 1
AND NOT EXISTS ( SELECT 1 FROM FailedLogins fl
WHERE fl.LoginUN = u.UserName
AND DATEDIFF('ss', fl.LoginTime, CURRENT_TIMESTAMP) >= 300 )
</cfquery>
您可以做的是向
checkUser
查询添加一个条件:
<cfquery name="checkUser" datasource="#dsn#">
SELECT UserName, Password, Salt, Active
FROM Users u
WHERE UserName = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(FORM.username)#" maxlength="50">
-- AND Active = 1
AND NOT EXISTS ( SELECT 1 FROM FailedLogins fl
WHERE fl.LoginUN = u.UserName
AND DATEDIFF('ss', fl.LoginTime, CURRENT_TIMESTAMP) >= 300 )
</cfquery>
我想你最好能改变你的逻辑。 而不是有一个列<代码>状态< /代码>值>代码>活动< /代码>或<代码>无效>代码>,考虑有一个列<代码> 最初,新用户的“锁定到”值将为NULL(或0),表示未锁定 当出现一系列登录失败时,将其设置为当前时间+5分钟 对于此用户的所有操作,请检查当前时间是否为>锁定\u直到值。 如果不是,则帐户仍处于停用(锁定)状态 编辑:我决定写一些代码,因为我忘了说明成功登录的用户。请参阅下文;我不确定最初的问题是用什么语言,但这个答案是伪python 假设我们有一个类似以下的数据库表(忽略盐类等) 登录检查功能如下所示。 重点是:
- 成功登录清除将失败登录设置为0
- 锁定帐户时,将FailedLogins设置为5(以及LockUntil)
- FailedLogins=5的新失败登录是对新解锁帐户的尝试。(即,帐户已隐式解锁,用户正在重试)
def try_登录(用户名、密码):
row=execute(“选择密码、锁定直至、用户名=?”的用户的失败登录、用户名);
如果行为“无”:
打印(“未知用户名”)
返回错误
如果row.lockintil不是None且当前_time()
我想你最好能把逻辑颠倒过来。
而不是有一个列<代码>状态< /代码>值>代码>活动< /代码>或<代码>无效>代码>,考虑有一个列<代码>
最初,新用户的“锁定到”值将为NULL(或0),表示未锁定
当出现一系列登录失败时,将其设置为当前时间+5分钟
对于此用户的所有操作,请检查当前时间是否为>锁定\u直到值。
如果不是,则帐户仍处于停用(锁定)状态
编辑:我决定写一些代码,因为我忘了说明成功登录的用户。请参阅下文;我不确定最初的问题是用什么语言,但这个答案是伪python
假设我们有一个类似以下的数据库表(忽略盐类等)
登录检查功能如下所示。
重点是:
- 成功登录清除将失败登录设置为0
- 锁定帐户时,将FailedLogins设置为5(以及LockUntil)
- FailedLogins=5的新失败登录是对新解锁帐户的尝试。(即,帐户已隐式解锁,用户正在重试)
def try_登录(用户名、密码):
row=execute(“选择密码、锁定直至、用户名=?”的用户的失败登录、用户名);
如果行为“无”:
打印(“未知用户名”)
返回错误
如果row.lockintil不是None且当前_time()CREATE TABLE Users (
UserName TEXT PRIMARY KEY,
Password TEXT NOT NULL,
LockUntil TIMESTAMP,
FailedLogins INT DEFAULT 0
);