流程:

用拦截器控制每一个页面请求和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. 让WIN7桌面显示IE图标

    首先新一个文本文件,将以下代码复制到新建文档中.然后保存为IE.reg,右键以管理员权限运行.此时,注册表注册成功.LOOK,IE图标出来了 Windows Registry Editor Versi ...

  2. InnoSQL HA Suite的实现原理与配置说明 InnoSQL的VSR功能Virtual Sync Replication MySQL 5.5版本引入了半同步复制(semi-sync replicaiton)的功能 MySQL 5.6支持了crash safe功能

    InnoSQL HA Suite的实现原理与配置说明  InnoSQL的VSR功能Virtual Sync Replication MySQL 5.5版本引入了半同步复制(semi-sync repl ...

  3. Bus System(Flody)

    http://acm.hdu.edu.cn/showproblem.php?pid=1690 坑爹的题,必须用__int64 %I64d(以前没用过) 因为这题的数据特别大,所以用-1 #includ ...

  4. PAT Maximum Subsequence Sum[最大子序列和,简单dp]

    1007 Maximum Subsequence Sum (25)(25 分) Given a sequence of K integers { N~1~, N~2~, ..., N~K~ }. A ...

  5. [LeetCode] 252. Meeting Rooms_Easy tag: Sort

    Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si ...

  6. Xcode 快捷键及代码格式化

    按住apple键点击类名就可以定位到这个类中查看相关定义(在日后的开发中我们会经常这么来做,毕竟要记住iOS开发中所有的API是不现实的,有些API我们可以通过这种方法来查找) PS:下面都是网上百度 ...

  7. Perl中的输入输出流(三)

    Perl中读取标准输入:<STDIN> foreach (<STDIN>)  { print "I saw $_";} 钻石操作符<>:它的参数 ...

  8. UNIX历史

    一.Multics计划 1965年,AT&T贝尔电话实验室.通用电气公司.麻省理工学院MAC课题组一起联合开发一个称为Multics的新操作系统. Multics 系统的目标是要向大的用户团体 ...

  9. css+div table

    div+css table表格样式 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  10. Multinoulli distribution

    https://www.statlect.com/probability-distributions/multinoulli-distribution3 Multinoulli distributio ...