流程:

用拦截器控制每一个页面请求和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(-, ErrCode.AuthError, "用户还未登录");
return new JsonResult
{
Data = errResponse,
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
} public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
}
}
}

控制登录管理:

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(-);
}
} 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;
}
}
}

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(, interval, ));
}
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);
}
}
}

其他:

 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; } }

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

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(-);

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

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

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

MVC5 一套Action的登录控制流程的更多相关文章

  1. MySQL数据库学习笔记(四)----MySQL聚合函数、控制流程函数(含navicat软件的介绍)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  2. MySQL聚合函数、控制流程函数(含navicat软件的介绍)

    MySQL聚合函数.控制流程函数(含navicat软件的介绍) 一.navicat的引入:(第三方可视化的客户端,方便MySQL数据库的管理和维护) NavicatTM是一套快速.可靠并价格相宜的数据 ...

  3. WebAPI 用ActionFilterAttribute实现token令牌验证与对Action的权限控制

    .NET WebAPI 用ActionFilterAttribute实现token令牌验证与对Action的权限控制 项目背景是一个社区类的APP(求轻吐...),博主主要负责后台业务及接口.以前没玩 ...

  4. MySQL聚合函数、控制流程函数

    [正文] 一.navicat的引入:(第三方可视化的客户端,方便MySQL数据库的管理和维护) NavicatTM是一套快速.可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设 ...

  5. JavaScript---js语法,数据类型及方法, 数组及方法,JSON对象及方法,日期Date及方法,正则及方法,数据类型转换,运算符, 控制流程(三元运算),函数(匿名函数,自调用函数)

    day46 一丶javascript介绍 JavaScript的基础分为三个       1.ECMAScript:JavaScript的语法标准.包括变量,表达式,运算符,函数,if语句,for语句 ...

  6. Azure Terraform(九)利用 Azure DevOps Pipeline 的审批来控制流程发布

    一,引言 Azure Pipeline 管道是一个自动化过程:但是往往我们由于某种原因,需要在多个阶段之前获得批准之后再继续下一步流程,所以我们可以向Azure Pipeline 管道添加审批!批准流 ...

  7. asp.net 一个简单的登录控制

    如果说一个网站需要用户登录后才能浏览,那么用户登录控制就不可避免.但是对于几百个以上的页面,不可能每个页面都做一次登录验证.因此,这需要在母版页中进行登录控制,这样就可以使得每一个使用这个母版页的子页 ...

  8. JavaScript(三)---- 控制流程语句

    常用的控制流程语句有判断语句.分支语句.循环语句.基本用法都和java中的一致,switch有几点特殊. 1.判断语句 格式:        if(判断条件){            符合条件执行的代 ...

  9. 【JAVA零基础入门系列】Day8 Java的控制流程

    什么是控制流程?简单来说就是控制程序运行逻辑的,因为程序一般而言不会直接一步运行到底,而是需要加上一些判断,一些循环等等.举个栗子,就好比你准备出门买个苹果,把这个过程当成程序的话,可能需要先判断一下 ...

随机推荐

  1. npm的用户名添加不上的原因

    npm添加不上的错误e401 1.用cnpm提交,会提交的tao.org这个域名了,用npm提交试试 2.如果npm提交不上,那就查看配置文件配置中 registry=http://registry. ...

  2. format格式化输出

    python格式化输出,format print("""********** Screen: {size} Density: {dpi} Device: {device} ...

  3. /etc/issue 查看系统版本号

    查看系统版本号 [root@mysql bin]# cat /etc/issue CentOS release 6.4 (Final) Kernel \r on an \m

  4. 全套 AR 应用设计攻略都在这里!

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/jILRvRTrc/article/details/79823908 通过将虚拟内容与现实世界融合,增 ...

  5. 11.sklearn.preprocessing.LabelEncoder的作用

    In [5]: from sklearn import preprocessing ...: le =preprocessing.LabelEncoder() ...: le.fit(["p ...

  6. [vue]vue条件渲染v-if(template)和自定义指令directives

    条件渲染: v-if/template <div id="app"> <h1>v-show: display: none</h1> <di ...

  7. QPixmap 显示大小

    size picSize(600,400); //将pixmap缩放成picSize大小然后保存在scaledPixmap中 按比例缩放: QPixmap scaledPixmap = pixmap. ...

  8. 对于session,request,cookie的理解

    session和request的生命周期 首先是session,比如我们在实现一个购物车功能时,在某一页面(这里称为页面A)选择了一些购物的商品,添加到购物车.那么当我们选择完成后点击我的购物车时会跳 ...

  9. Jtester+unitils+testng:DAO单元测试文件模板自动生成

    定位 本文适合于不愿意手工编写而想自动化生成DAO单元测试的筒鞋.成果是不能照搬的,但其中的"创建模板.填充内容.自动生成"思想是可以复用的.读完本文,可以了解 Python 读取 ...

  10. MyBatis学习笔记(六)——调用存储过程

    转自孤傲苍狼的博客:http://www.cnblogs.com/xdp-gacl/p/4270352.html 一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据 ...