問題描述
之前沒有使用Forms身份驗證時,如果在登陸過程中把持久的Cookie過期時間設為半個小時,總會收到很多用戶的抱怨,說登陸一會就過期了。
所以總是會把Cookie過期時間設的長一些,比如兩個小時甚至一天,這樣就能保證在登陸時設置一次Cookie,用戶可以操作很長時間也不過期。
雖然也可以在每次用戶請求頁面時檢查Cookie的過期時間並自動擴展,但未免過於麻煩,不如一次設大點來的簡單。
偶然發現
今天在使用Forms身份驗證編寫《AppBox-基於ExtAspNet的企業通用管理框架》時,想當然的在Web.config中這么設置:
<authentication mode="Forms"> <forms name=".ASPXFORMSAUTH" loginUrl="~/default.aspx" timeout="360" defaultUrl="~/main.aspx" protection="All" path="/"/> </authentication>
我把過期時間設為了6個小時,以期望在登陸后的 6 個小時內不會聽到用戶的抱怨。
由於希望把用戶所屬的角色也一並保存到User.Identity中,在查閱關於自定義的身份驗證時無意發現這篇文章中的一段話:
若不是持久Cookie,Cookie的有效期Expiration屬性有當前時間加上web.config中timeout的時間,每次請求頁面時,在驗證身份過程中,會判斷是否過了有效期的一半,要是的話更新一次cookie的有效期
太棒了!如果真是這樣,所謂的timeout屬性根本不太重要,系統會在每次請求頁面時重新判斷過期時間,如果快過期了就自動擴展。
注:上面引用的這段話有問題,對於持久Cookie才有過期時間的說法,非持久Cookie一般也稱為會話Cookie,不能跨瀏覽器進程存在,所以關閉瀏覽器就消失了。
親自驗證
真正的學習和領會就需要親自動手了,下面幾個步驟會帶領我們驗證上面的說法(下面截圖中使用的是FireFox + FireBug + FireCookie)。
1. 配置Web.config
<authentication mode="Forms"> <forms name=".ASPXFORMSAUTH" loginUrl="~/default.aspx" timeout="2" defaultUrl="~/main.aspx" protection="All" path="/"/> </authentication>
我們把過期時間設為 2 分鍾,以方便觀察Cookie的過期時間。
2. 登陸代碼
在登陸成功的代碼中,通過下面語句代碼完成Cookie的寫入和頁面的跳轉(第二個參數表明這是一個持久Cookie):
FormsAuthentication.RedirectFromLoginPage(userName, true);
3. 觀察登陸后的Cookie信息
由於我們是在 2012-6-22 9:04:12 登陸的,所以這里的過期時間是 2012-6-22 9:06:12
4. 在登陸 1 分鍾內刷新頁面
一分鍾內刷新頁面,Cookie的過期時間沒有變化,和上圖一樣。
5. 在登陸 1 分鍾后刷新頁面
在 9:05:13 刷新的頁面,也就是剛剛過去 1 分鍾,系統會自動擴展Cookie過期時間,在此基礎上再增加 2 分鍾,所以現在的過期時間是 9:07:13
6. 在登陸 2 分鍾后刷新頁面
兩分鍾后刷新,Cookie過期,頁面會自動跳轉到登陸頁面。
總結
Asp.Net的Forms身份驗證不僅為我們提供了一致和安全的驗證手段, 而且這種自動擴展Cookie過期時間的機制更是錦上添花,讓我們有更多的時間關注於業務邏輯的實現。