摘要: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 之前 加上
經過對瀏覽器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));
人生到處知何似
應似飛鴻踏雪泥