Form 认证无刷新实现

最近遇到一个问题,就是部分低端手机登陆后Form认证成功Cookie 丢失,

无奈之下用办法尝试解决保存用FormsAuthentication.SetAuthCookie() 后直接获取 HttpContext.Current.User.Identity.IsAuthenticated 为True.


由于Form 认证后加密及时把信息保存在Cookie中,本次请求无法获取到登录状态,必须等刷新后吧数据Response 后到下一个request中 才可以后期到Request. IsAuthenticated 的值。

目前现状就是这样,问题是部分手机自带浏览器会把form认证Cookie信息丢失,为了兼容这部分手机,

1、登录信息保存在在数据库或文件缓存中,然后把加密后的索引值负责url 中。通过判断url然后获取缓存数据判断用户登录。

2、由于项目都是通过form认证判断用户登录的,如果所有判断会耗费大量时间和精力,必须实现在同一个请求页面实现 FormsAuthentication.SetAuthCookie() 用户登录信息的缓存,

同时还必须获取用户认证信息 Request. IsAuthenticated 。

3、由于在同一个请求中保存认证的Cookie信息还没有Response到客户端,根本无法获取Request.IsAuthenticated 值,查看HttpRequest源码可以发现获取获取值  context.User.Identity.IsAuthenticated 值。  

public bool IsAuthenticated {
            get {
                if (context.User == null || context.User.Identity == null)
                    return false;
                return context.User.Identity.IsAuthenticated;
            }
        }

我们可以手动生产一个用户安全认证信息,方便与如用户控件LogView识别(LogView控件依赖form认证后触发viewchange事件),我们直接给用户信息保存到Context.User 如:

 System.Web.Security.FormsAuthentication.SetAuthCookie(userName, false);
                       
Context.User = new GenericPrincipal(new GenericIdentity(userName, "Forms"), null);

此时,完成更新form中保存用户信息后, HttpContext.Current.User.Identity.IsAuthenticated 的值为True 了。 loginView 会自动触发转换为登录用户状态,

当然 后可以使用其他方法实现,如下需要用户其他更完整更新用户信息可以参考如下:

 public void RenewCurrentUser()
        {
            System.Web.HttpCookie authCookie =
                System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie != null)
            {
                FormsAuthenticationTicket authTicket = null;
                authTicket = FormsAuthentication.Decrypt(authCookie.Value);

                if (authTicket != null && !authTicket.Expired)
                {
                    FormsAuthenticationTicket newAuthTicket = authTicket;

                    if (FormsAuthentication.SlidingExpiration)
                    {
                        newAuthTicket = FormsAuthentication.RenewTicketIfOld(authTicket);
                    }
                    string userData = newAuthTicket.UserData;
                    string[] roles = userData.Split(',');
                    Context.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), null);
                    System.Web.HttpContext.Current.User =
                        new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), roles);
                    
                }
            }
        }

 

原文地址:https://www.cnblogs.com/andyyu/p/2203615.html