Form驗證中一個奇怪的問題

摘要:Form驗證中一個奇怪的問題

使用ASP.NET 自帶的Form驗證機制,發現在驗證通過,要使用自定義的UserData時, 頁面轉向方式會造成UserData無法取到的問題.

步驟如下:

1. 驗證通過.(略去)

2. 把識別碼寫入Cookie

   FormsAuthentication.SetAuthCookie(UserName, False)

3. 寫入自定義UserData

   Dim strUserData as String = "...."

   Dim objTicket = New FormsAuthenticationTicket(1, info.UserName, DateTime.Now, DateTime.Now.AddMinutes(20), RemeberMe, strUserData)

   Dim objHashTicket = FormsAuthentication.Encrypt(objTicket)
 
   Dim objCookie = New HttpCookie(FormsAuthentication.FormsCookieName, objHashTicket)
 
   Response.Cookies.Add(objCookie)
 
4. 轉向
 
    Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName, RemeberMe))
    ' 以上方法不能持久保存COOKIE.
    FormsAuthentication.RedirectFromLoginPage(objModel.UserName, objModel.RememberMe) 
    以上方法保證COOKIE能保存(用Remember Me選項).不然關掉瀏覽器狀態就消失了. 問題是讀不出UserData. 因為此方法會覆蓋自定義COOKIE,所以無法取得原先設定的UserData.
   注意: UserData 要存簡單字串, 序列化的對象 不要存入其中.
   
  終極解決方案:
   經過對瀏覽器Cookie的觀察,發現RedirectFromLoginPage為何能保存持久的Cookie是因為他設定的非進程間Cookie,也就是不是Session的Cookie,所以如果 同時要滿足1.能夠保存UserData ,2. 要保存狀態.  就應該 加一句段代碼, 在存儲objCookie 之前 加上
 objAuthCookie.Expires = DateTime.Now.AddMinutes(20) 即可,指定存儲的Cookie在Session丟失時依然保存與瀏覽器中.如下:
 

Dim strUserData as String = "...."
Dim objTicket = New FormsAuthenticationTicket(1, info.UserName, DateTime.Now, DateTime.Now.AddMinutes(20), RemeberMe, strUserData)
Dim objHashTicket = FormsAuthentication.Encrypt(objTicket)
Dim objCookie = New HttpCookie(FormsAuthentication.FormsCookieName, objHashTicket)
objCookie.Expires = DateTime.Now.AddMinutes(20) 
Response.Cookies.Add(objCookie)
 
  參考
 
 我们可以使用下面 4 种方法中的一种进行票证写入和重定向操作,其实前 3 种只不过是对第 4 种方法的封装而已。推荐使用 1、4。注意后三种方法不支持cookieless="UseUri"。

// 1. 使用缺省身份验证票证(不適合使用到UserData[自定義Cookie]的時候)
FormsAuthentication.RedirectFromLoginPage("username", true);

// 2. 使用缺省身份验证票证
FormsAuthentication.SetAuthCookie("username", false);
Response.Redirect(FormsAuthentication.GetRedirectUrl("username", false));

// 3. 使用缺省身份验证票证
Response.Cookies.Add(FormsAuthentication.GetAuthCookie("username", false));
Response.Redirect(FormsAuthentication.GetRedirectUrl("username", false));

// 4. 使用自定义身份验证票证
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "username", DateTime.Now, DateTime.Now.AddMinutes(10), false, null);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket)));
Response.Redirect(FormsAuthentication.GetRedirectUrl("username", false));
   

人生到處知何似
應似飛鴻踏雪泥