zoukankan      html  css  js  c++  java
  • 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个就是我踩的坑,以后注意!

  • 相关阅读:
    Java垃圾收集学习笔记
    好IT男不能“淫”-谈IT人员目前普遍存在的“A情绪”
    亲密接触Redis-第三天(Redis的Load Balance)
    数据库面试常问的一些基本概念
    Mina的ssl加密
    Mina入门教程(二)----Spring4 集成Mina
    Mina Session
    Mina入门实例(一)
    java keytool生成ssl加密密钥
    Python学习(一)——数据类型
  • 原文地址:https://www.cnblogs.com/hongdada/p/7286832.html
Copyright © 2011-2022 走看看