• MVC5 一套Action的登录控制流程


    流程:

    用拦截器控制每一个页面请求和ajax请求,根据请求体的cookie里面是否有token判断是否登录,还必须判断该token在redis里面的缓存是否存在

    组成部分:

    拦截器:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.Mvc;
    using Rongzi.RZR.Huoke.Infrastructure.Util;
    using Rongzi.RZR.Huoke.Entity;
    using Rongzi.RZR.Huoke.Entity.Constants;
    using Rongzi.RZR.Huoke.Infrastructure.Model;
    using Rongzi.RZR.Huoke.Entity.Models;
    
    namespace Rongzi.RZR.Huoke.Infrastructure.Filter
    {
       public  class ApiAuthFilterAttribute:System.Web.Mvc.ActionFilterAttribute
        {
            public bool isDoCheck { get; set; }
            public ApiAuthFilterAttribute()
            {
                isDoCheck = true;
            }
            public ApiAuthFilterAttribute(bool isCheck = true)
            {
                isDoCheck = isCheck;
            }
    
            public override void OnActionExecuting(ActionExecutingContext actionContext)
            {
                if (isDoCheck)
                {
    
                    if (actionContext == null || actionContext.HttpContext.Request == null || actionContext.HttpContext.Request.RawUrl == null) { return; }
                    //string token = actionContext.HttpContext.Request.Headers["token"] ?? actionContext.HttpContext.Request.Cookies["token"].Value;
     
                    string token = actionContext.HttpContext.Request.Cookies["token"]?.Value;
                    if (string.IsNullOrEmpty(token))
                    {
                        if (actionContext.HttpContext.Request.IsAjaxRequest())
                        {
                            actionContext.Result = GetAuthJsonResult();
                        }
                        else
                        {
                            actionContext.HttpContext.Response.Redirect("~/Account/Login");
                        }
                        return;
                    }
                    RedisOpearteResult redRes = TokenManager<OrganizationUser>.RefreshUserToken(token);
                    if (!redRes.isok)
                    {
                        if (actionContext.HttpContext.Request.IsAjaxRequest())
                        {
                            actionContext.Result = GetAuthJsonResult();
                        }
                        else
                        {
                            actionContext.HttpContext.Response.Redirect("~/Account/Login");
                        }
                        base.OnActionExecuting(actionContext);
                        return;
                    }
                }
                base.OnActionExecuting(actionContext);
            }
    
    
            public static JsonResult GetAuthJsonResult()
            {
                var errResponse = new ResponseContext<string>();
                errResponse.Head = new ResponseHead(-1, ErrCode.AuthError, "用户还未登录");
                return new JsonResult
                {
                    Data = errResponse,
                    ContentEncoding = System.Text.Encoding.UTF8,
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
            }
    
            public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
            {
                base.OnActionExecuted(actionExecutedContext);
            }
        }
    }
    View Code

    控制登录管理:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using Rongzi.RZR.Huoke.Entity.Models;
    using Rongzi.RZR.Huoke.Infrastructure.Util;
    using Rongzi.RZR.Huoke.Infrastructure.Model;
    
    namespace Rongzi.RZR.Huoke.Infrastructure
    {
        public class FormsAuth
        {
            ///// <summary>
            ///// 生成Userdata
            ///// </summary>
            ///// <param name="user">用户model</param>
            ///// <returns></returns>
            //private static string GenerateUserData(long userId, string userName, string userAccount, string imageUrl)
            //{
            //    return string.Join("|", userId, userName, userAccount, imageUrl);
            //}
    
            ///// <summary>
            ///// 登录系统
            ///// </summary>
            ///// <param name="user">用户model</param>
            ///// <param name="isRemember"是否记住></param>
            ///// <param name="days">超时时间</param>
            //public static void SignIn(long userId, string userName, string userAccount, string imageUrl, bool isRemember, int days)
            //{
            //    var userData = GenerateUserData(userId, userName, userAccount, imageUrl);
            //    var enyUserData = DEncrypt.Encrypt(userData);
            //    var ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddDays(days), isRemember, enyUserData);
            //    var enyTicket = FormsAuthentication.Encrypt(ticket);
    
            //    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, enyTicket);
    
            //    HttpContext.Current.Response.Cookies.Add(authCookie);
            //}
    
            /// <summary>
            /// 登录系统
            /// </summary>
            /// <param name="user"></param>
            public static void SignIn(OrganizationUser user)
            {
                RedisOpearteResult result = TokenManager<OrganizationUser>.getToken(user);
                var authCookie = new HttpCookie("token", result.token);
                HttpContext.Current.Response.SetCookie(authCookie);
               
            }
    
            /// <summary>
            /// 退出系统
            /// </summary>
            /// <param name="token"></param>
            public static void SignOff()
            {
                var cookie = HttpContext.Current.Request.Cookies["token"];
                if (cookie != null)
                {
                    string token = cookie.Value;
                    TokenManager<OrganizationUser>.LoginOff(token);
                    HttpContext.Current.Response.Cookies["token"].Expires = DateTime.Now.AddDays(-1);
                }
            }
    
            public static OrganizationUser GetUserInfo()
            {
                var cookie = HttpContext.Current.Request.Cookies["token"];
                if (cookie != null)
                {
                    string token = cookie.Value;
                    return TokenManager<OrganizationUser>.getUserByToken(token);
                }
                return null;
            }
        }
    }
    View Code

    TokenManager管理:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Newtonsoft.Json;
    using Rongzi.Cache.Redis;
    using System.Configuration;
    using Rongzi.RZR.Huoke.Infrastructure.Model;
    
    namespace Rongzi.RZR.Huoke.Infrastructure.Util
    {
        public class TokenManager<TUser>
        {
            /// <summary>
            /// 设置对象过期时间
            /// </summary>
            private static readonly int interval = Convert.ToInt32(ConfigurationManager.AppSettings["Redis_UserExpire"]);
            private static readonly string prefix = "OrganizationUser:";
    
            /// <summary>
            /// 存储对象val,获取对应的token
            /// </summary>
            /// <param name="val"></param>
            /// <returns></returns>
            public static RedisOpearteResult getToken(TUser val)
            {
                string tokenID = Guid.NewGuid().ToString();
                RedisOpearteResult result = new RedisOpearteResult
                {
                    isok = RedisCache.Add(prefix + tokenID, val, interval),
                    token = tokenID,
                    result = JsonConvert.SerializeObject(val)
                };
                return result;
            }
    
            /// <summary>
            /// 根据tokenID更新用户对象
            /// </summary>
            /// <param name="tokenID"></param>
            /// <param name="val"></param>
            /// <returns></returns>
            public static RedisOpearteResult RefreshLoginTokenData(String tokenID, TUser val)
            {
                RedisOpearteResult result = new RedisOpearteResult
                {
                    isok = RedisCache.Add(prefix + tokenID, val, interval),
                    token = tokenID,
                    result = JsonConvert.SerializeObject(val)
                };
                return result;
            }
    
            /// <summary>
            /// 刷新用户token
            /// </summary>
            /// <param name="tokenID"></param>
            public static RedisOpearteResult RefreshUserToken(string tokenID)
            {
                var obj = RedisCache.Get<TUser>(prefix + tokenID);
                var isExist = obj != null;
                RedisOpearteResult result = new RedisOpearteResult
                {
                    isok = isExist,
                    token = tokenID,
                    result = "Token过期"
                };
                if (isExist)
                {
                    result.result = "成功延迟";
                    RedisCache.SetExpire(prefix + tokenID, new TimeSpan(0, interval, 0));
                }
                return result;
            }
    
            /// <summary>
            /// 退出
            /// </summary>
            /// <param name="tokenID"></param>
            /// <returns></returns>
            public static RedisOpearteResult LoginOff(string tokenID)
            {
                var obj = RedisCache.Get<TUser>(prefix + tokenID);
                var isExist = obj != null;
                RedisOpearteResult result = new RedisOpearteResult
                {
                    isok = isExist,
                    token = tokenID,
                    result = "Token过期"
                };
                if (isExist)
                {
                    result.result = "退出成功";
                    RedisCache.Remove(prefix + tokenID);
                }
                return result;
            }
    
            /// <summary>
            /// 通过token 获取用户信息
            /// </summary>
            /// <param name="token">tokenID</param>
            /// <returns></returns>
            public static TUser getUserByToken(string tokenID)
            {
                if (!string.IsNullOrEmpty(tokenID))
                {
                    return RedisCache.Get<TUser>(prefix + tokenID);
                }
                return default(TUser);
            }
        }
    }
    View Code

    其他:

     public class RedisOpearteResult
        {
            public string token { get; set; }
            public bool isok { get; set; }
            public int code { get; set; }
            public object data { get; set; }
            public string result { get; set; }
    
        }
    View Code

    其实整个流程不难,下面说说坑:

    Cookie的修改

    登录时,不能使用

     HttpContext.Current.Response.Cookies.Add(authCookie);

    这个是不断的添加cookie,有相同路径的,就添加不同路径的

    应该使用:

     HttpContext.Current.Response.SetCookie(authCookie);

    这个才是唯一性的,有就修改,没有就添加

    Cookie的删除:

    HttpContext.Current.Response.Cookies.Remove("token");

    这个是旧的使用方式,发现怎么也没有用,浏览器中还是有这个cookie,后来查询资料,这个就对服务器中的cookies进行删除,但是并不对浏览器中的cookie进行操作。

    应该使用过期时间:

     HttpContext.Current.Response.Cookies["token"].Expires = DateTime.Now.AddDays(-1);

    还有一点,获取cookie的信息的时候使用Request的,不要使用Response的,发现对象存在,但是里面的值是空字符串

    var cookie = HttpContext.Current.Request.Cookies["token"];

    上面3个就是我踩的坑,以后注意!

  • 相关阅读:
    华为云确定性运维,为政务云平台稳定可靠运行保驾护航
    实践GoF的设计模式:代理模式
    KubeEdge 1.12版本发布,稳定性、安全性、可扩展性均带来大幅提升
    使用Mask RCNN模型实现人体关键节点标注
    Vue 中为什么要有nextTick?
    后CNN探索,如何用RNN进行图像分类
    带你认识JDK8中超nice的Native Memory Tracking
    实例分析Scheduled Thread Pool Executor与Timer的区别
    最后 3 天|报名参加 OpenYurt+EdgeX 挑战赛 ,冲击最高 5 万元奖励!
    定时任务报警通知解决方案详解
  • 原文地址:https://www.cnblogs.com/hongdada/p/7286832.html
Copyright © 2020-2023  润新知