天天看點

艾偉:較為周全的Asp.net送出驗證方案(Session版)提示:

艾偉:較為周全的Asp.net送出驗證方案(Session版)提示:

此前我介紹了使用資料庫實作的送出驗證方案,一些朋友懷疑其效率不佳,認為Session是更好的方案。

的确使用Session也不會消耗太多記憶體,而且如今記憶體白菜價,最不濟就随手買個2G的插上也就夠了,是以我将在此寫下Session版的實作提要,其餘細節參考前篇。

在Session中存儲一個哈希表用以記錄該使用者的每一條驗證資訊,哈希表的鍵為驗證資訊的過期時間,值為驗證碼的明文。

過期時間使用ViewState存儲,以發給用戶端,并在送出時擷取,以讀取對應的驗證碼明文。

傳給驗證碼生成頁面的ID參數是經ToFileTime()方法轉換的過期時間,驗證碼生成頁擷取到此參數後進行逆轉換,再讀取對應的驗證碼明文以生成顯示。

先建立一個靜态類,名為“送出驗證”,将用于存儲驗證資訊的Session變量封裝為一個屬性:

///

/// 驗證資訊表

static Hashtable 驗證資訊

{

    get

    {

        return Core.函數庫.網絡.Session["驗證資訊"] as Hashtable;

    }

    set

        Core.函數庫.網絡.Session["驗證資訊"] = value;

}

清理方法,用于将過期的資料清除:

/// 清理所有過期的驗證資訊

public static void 清理()

    if (驗證資訊 == null || 驗證資訊.Count < 5) return;

    foreach (DictionaryEntry f in (Hashtable)驗證資訊.Clone())

        if ((DateTime)f.Key < DateTime.Now) 驗證資訊.Remove(f);

小于5條驗證資訊則忽略。

克隆一個驗證資訊表供foreach使用,如果使用原表循環的話,直接移除内容會改變表長度,進而引發異常。

添加方法:

/// 添加一個新的驗證資訊。

/// 驗證碼">要儲存的驗證碼

/// 過期時間內插補點">用于計算過期時間,機關為分鐘

/// 過期時間戳

public static DateTime 添加(string 驗證碼, byte 過期時間內插補點)

    清理();

    var 過期時間 = DateTime.Now.AddMinutes(過期時間內插補點);

    if (驗證資訊 == null) 驗證資訊 = new Hashtable();

    驗證資訊.Add(過期時間, 驗證碼);

    return 過期時間;

在添加前進行過期資訊清理工作。

擷取、驗證、移除方法:

/// 根據過期時間戳擷取對應的驗證碼

/// 過期時間戳">驗證資訊過期時間戳

/// 驗證碼明文

public static string 擷取(DateTime 過期時間戳)

    return 驗證資訊[過期時間戳] as string;

/// 驗證使用者輸入的驗證碼是否正确

/// 驗證碼">使用者輸入的驗證碼

/// 傳回錯誤資訊,如驗證成功則傳回null

public static string 驗證(DateTime 過期時間戳, string 驗證碼)

    if (過期時間戳 < DateTime.Now) return "驗證資訊已過期";

    var 驗證碼明文 = 擷取(過期時間戳);

    if (驗證碼明文 == null) return "驗證資訊無效或已過期";

    else if (驗證碼明文.ToLower() != 驗證碼.ToLower()) return "驗證碼錯誤";

    else return null;

/// 根據過期時間戳移除對應的驗證資訊

public static void 移除(DateTime 過期時間戳)

    驗證資訊.Remove(過期時間戳);

使用時在頁面上封裝一個基于ViewState屬性:

/// 時間戳屬性,基于ViewState

public DateTime? 時間戳

        return ViewState["時間戳"] as DateTime?;

        ViewState["時間戳"] = value;

然後在load事件中調用:

protected void Page_Load(object sender, EventArgs e)

    if (!IsPostBack)

        時間戳 = 送出驗證.添加();

        Image1.ImageUrl = "~/VerifyImage.aspx?ID=" + 時間戳.Value.ToFileTime();

(無參數的“添加”方法是我實作的一個擴充卡封裝方法,采用預設的過期時間設定,随機生成驗證碼)

送出時的調用:

protected void Button1_Click(object sender, EventArgs e)

    var s = 送出驗證.驗證(時間戳.Value, TextBox1.Text);

    if (s == null)

        CustomValidator1.IsValid = true;

        //送出...

        送出驗證.移除(時間戳.Value);

    else

        CustomValidator1.IsValid = false;

        CustomValidator1.ErrorMessage = s;

驗證碼生成時,建議隻采用這些字元:2345678abcdefghijkmnprstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ

這裡放棄了一些容易産生視覺混淆的字元,比如1和I、l,0和O、o,減少使用者撓牆、砸電腦的可能。