天天看點

[C#]winform使用者登入狀态之時間驗證

今天做了一個小的登入程式,要求是使用者連續登入錯誤3次之後鎖定該使用者,過了一定的時間才能再次登入。于是乎在探讨的時候出現了以下的代碼:
           
private void UpdateErrortime()
{
    SqlConnection conn = new SqlConnection(strcon);
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = conn;
    conn.Open();
    cmd.CommandText = "update T_User set [email protected] where [email protected]";
    cmd.Parameters.AddWithValue("errortime",DateTime.Now);
    cmd.Parameters.AddWithValue("@username",txtUserName.Text);
    cmd.ExecuteNonQuery();
}

DateTime errortime = GetErrorTime();
//Subtract函數減去指定時間,傳回一個時間差,這個傳回值可以轉換成我們需要的形式,比如可以轉換層總共多少秒,或者總共是多少分。。。
TimeSpan span = DateTime.Now.Subtract(errortime);
double theseconds = span.TotalSeconds;
if (theseconds < 15)
{
    MessageBox.Show("您已經連續3次輸入錯誤的密碼,已被系統鎖定,請15秒之後再次重試,或者到服務視窗解鎖");
    //程式執行到此為止,後面代碼不再執行
    return;
}
else
{
    errorcount = 0;
    UpdateError(errorcount);
}
           
這段代碼看似沒有問題,但實際應用中會發現隻需要修改本地的時間,就能繞過鎖定登入的限制,而用以下代碼則不會産生問題:
int secondspan = GetErrorTime1();
//如果間隔時間小于解鎖時間則傳回程式
if (secondspan < 15)
{
    MessageBox.Show("您已經連續3次輸入錯誤的密碼,已被系統鎖定,請15秒之後再次重試,或者到服務視窗解鎖");
    //程式執行到此為止,後面代碼不再執行
    return;
}


private int GetErrorTime1()
{
    SqlConnection conn = new SqlConnection(strcon);
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = conn;
    conn.Open();
    cmd.CommandText = "select DATEDIFF([second],ErrorTime,getdate()) from T_User where [email protected]";
    cmd.Parameters.AddWithValue("@username", txtUserName.Text);
    //傳回一行一列
    object obj = cmd.ExecuteScalar();
    return Convert.ToInt32(obj);
}
           
BUG總結:
使用者鎖定的時間是通過用戶端時間驗證的而不是伺服器,通過完全調用伺服器的時間來做判斷,就能完美解決這一問題。