.Net Core MVC 基于Cookie进行用户认证
在打代码之前先说一下思路。
登录的的时候服务端生成加密的字符串(用户名、id、当前时间)并且存入客户端cookie中,服务端的缓存中。对客户端的每次请求进行拦截,解密保存在cookie中的加密字符串。查看是否已过期,如果已过期跳转到登录页,并且删除cookie与缓存中的数据。如未过期修改缓存中的时间,并进行下一步操作。
加密解密的代码
引入包:Microsoft.Extensions.Configuration(读配置文件的时候会用到,加密key与解密key最好存在配置文件中,从配置文件中读取)
public class Encryption
{
private IConfiguration _configuration;
public Encryption(IConfiguration configuration)
{
_configuration = configuration;
} public byte[] EncrKey()
{
return ASCIIEncoding.ASCII.GetBytes(_configuration["MD5:EncrKey"]);
}
public byte[] DecrKey()
{
return ASCIIEncoding.ASCII.GetBytes(_configuration["MD5:DecrKey"]);
} /// <summary>
/// DES加密
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public async Task<string> Encrypt(string str)
{
MemoryStream ms = null;
CryptoStream cs = null;
StreamWriter sw = null; DESCryptoServiceProvider des = new DESCryptoServiceProvider();
try
{
var s= ASCIIEncoding.ASCII.GetBytes(_configuration["MD5:EncrKey"]);
ms = new MemoryStream();
cs = new CryptoStream(ms, des.CreateEncryptor(this.EncrKey(), this.DecrKey()), CryptoStreamMode.Write);
sw = new StreamWriter(cs);
sw.Write(str);
sw.Flush();
cs.FlushFinalBlock();
return Convert.ToBase64String(ms.GetBuffer(), , (int)ms.Length);
}
finally
{
if (sw != null) sw.Close();
if (cs != null) cs.Close();
if (ms != null) ms.Close();
}
} /// <summary>
/// DES解密
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public async Task<string> Decrypt(string str)
{
MemoryStream ms = null;
CryptoStream cs = null;
StreamReader sr = null; DESCryptoServiceProvider des = new DESCryptoServiceProvider();
try
{
ms = new MemoryStream(Convert.FromBase64String(str));
cs = new CryptoStream(ms, des.CreateDecryptor(this.EncrKey(), this.DecrKey()), CryptoStreamMode.Read);
sr = new StreamReader(cs);
return sr.ReadToEnd();
}
finally
{
if (sr != null) sr.Close();
if (cs != null) cs.Close();
if (ms != null) ms.Close();
}
}
}
操作Redis
引入包:StackExchange.Redis
连接字符串最好也存入配置文件中
public class RedisContent
{
public StackExchange.Redis.ConnectionMultiplexer Redis = null;
public StackExchange.Redis.IDatabase db = null; public RedisContent(IConfiguration configuration)
{
_configuration = configuration;
this.Redis = ConnectionMultiplexer.Connect($"{_configuration["Redis:dbconn"]}");
this.db = this.Redis.GetDatabase();
}
private IConfiguration _configuration;
}
定义一个特性类,对于一些不需要认证的接口,加上这个特性即可。相当于微软的[AllowAnonymous]认证中间件。这里的话我们自己写一个。
public class AllowAuthAttribute : Attribute
{
}
添加过滤器AuthorizeFilter。上面封装的一些方法,全部以注入的形式进行使用。
public class AuthorizeFilter : Attribute, IAuthorizationFilter
{
private readonly ILogger<AuthorizeFilter> _logger;
private readonly RedisContent _content;
private readonly Encryption _encryption;
public AuthorizeFilter(RedisContent content,
Encryption encryption,
ILogger<AuthorizeFilter> logger)
{
_content = content;
_encryption = encryption;
_logger = logger;
} public void OnAuthorization(AuthorizationFilterContext context)
{
var isDefined = false;
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor != null)
{
//判断请求的控制器和方法有没有加上AllowAuthAttribute(不需要认证)
isDefined = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
.Any(a => a.GetType().Equals(typeof(AllowAuthAttribute)));
}
if (isDefined) return;
if (context.HttpContext.Request.Path == "/")
return;
string value = string.Empty;
context.HttpContext.Request.Cookies.TryGetValue("userinfo", out value);
if (string.IsNullOrEmpty(value))
context.HttpContext.Response.Redirect("https://localhost:44300/");
else
{
//解密cookie
var decryptValueArray = _encryption.Decrypt(value).Result.Split("|");
string user = _content.db.StringGet($"{decryptValueArray[0]}-{decryptValueArray[2]}");
if (string.IsNullOrEmpty(user) || !user.Equals(value))
{
_logger.LogError($"Token已过期/有误! Url:{context.HttpContext.Request.Path}");
context.HttpContext.Response.Cookies.Delete("userinfo");
context.HttpContext.Response.Redirect("https://localhost:44300/");
}
else
{
//重新设置key的时间
_content.db.KeyExpire($"{decryptValueArray[0]}-{decryptValueArray[2]}", TimeSpan.FromMinutes());
return;
}
}
}
}
编写控制器中的代码
/// <summary>
/// 验证登录 颁发Token 存入cookie
/// </summary>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <returns></returns>
[AllowAuth]
public async Task<IActionResult> LoginUser(string userName, string password)
{
if (string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(password))
return Json(new { success = false, msg = "用户名或密码不能为空" });
//带参查询
var data = await _userInfoServices.QueryUserInfo(userName, password);
if (data.Any())
{
//得到uid,将uid也带进token中加密
var uid = data.ToList()[].id;
//加密 30分钟的有效期
var token = await _encryption.Encrypt(userName + "|" + DateTime.Now + "|" + uid + "|" + );
//存入redis中
_content.db.StringSet($"{userName}" + "-" + uid, token, TimeSpan.FromMinutes());
//存入cookie中
Response.Cookies.Append("userinfo", token);
return Json(new { success = true, msg = "登陆成功" });
}
else
{
return Json(new { success = false, msg = "用户名或密码输入错误" });
}
}
如有不足,还望见谅!
.Net Core MVC 基于Cookie进行用户认证的更多相关文章
- Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录
1.登录的实现 登录功能实现起来有哪些常用的方式,大家首先想到的肯定是cookie或session或cookie+session,当然还有其他模式,今天主要探讨一下在Asp.net core 2.0下 ...
- 理解ASP.NET Core - 基于Cookie的身份认证(Authentication)
注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 概述 通常,身份认证(Authentication)和授权(Authorization)都会放 ...
- Laravel 5 中使用 JWT(Json Web Token) 实现基于API的用户认证
在JavaScript前端技术大行其道的今天,我们通常只需在后台构建API提供给前端调用,并且后端仅仅设计为给前端移动App调用.用户认证是Web应用的重要组成部分,基于API的用户认证有两个最佳解决 ...
- JWT 实现基于API的用户认证
基于 JWT-Auth 实现 API 验证 如果想要了解其生成Token的算法原理,请自行查阅相关资料 需要提及的几点: 使用session存在的问题: session和cookie是为了解决http ...
- 5分钟搞懂:基于token的用户认证
https://www.qikegu.com/easy-understanding/880 用户认证 用户认证或者说用户登录是确认某人确实是某人的过程,生活中靠身份证,网络上就要靠账号和密码.用户提供 ...
- 项目一:第十一天 2、运单waybill快速录入 3、权限demo演示-了解 5、权限模块数据模型 6、基于shiro实现用户认证-登录(重点)
1. easyui DataGrid行编辑功能 2. 运单waybill快速录入 3. 权限demo演示-了解 4. Apache shiro安全框架概述 5. 权限模块数据模型 6. 基于shiro ...
- Linux下基于LDAP统一用户认证的研究
Linux下基于LDAP统一用户认证的研究 本文出自 "李晨光原创技术博客" 博客,谢绝转载!
- 基于cookie的用户登录状态管理
cookie是什么 先来花5分钟看完这篇文章:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies 看完上文,相信大家对cookie已经有 ...
- net core体系-web应用程序-4asp.net core2.0 项目实战(1)-12基于cookie登录授权认证并实现前台会员、后台管理员同时登录
1.登录的实现 登录功能实现起来有哪些常用的方式,大家首先想到的肯定是cookie或session或cookie+session,当然还有其他模式,今天主要探讨一下在Asp.net core 2.0下 ...
随机推荐
- ASP.NET Core - 在ActionFilter中使用依赖注入
上次ActionFilter引发的一个EF异常,本质上是对Core版本的ActionFilter的知识掌握不够牢固造成的,所以花了点时间仔细阅读了微软的官方文档.发现除了IActionFilter.I ...
- 使用burp插件captcha-killer识别图片验证码
0x01 开发背景 说起对存在验证码的登录表单进行爆破,大部分人都会想到PKav HTTP Fuzzer,这款工具在前些年确实给我们带来了不少便利.反观burp一直没有一个高度自定义通杀大部分图片验证 ...
- 免费开源数字货币交易所——基于Java开发的比特币交易所 | BTC交易所 | ETH交易所 | 数字货币交易所
本项目是基于Java开发的比特币交易所 | BTC交易所 | ETH交易所 | 数字货币交易所 | 交易平台 | 撮合交易引擎.本项目基于SpringCloud微服务开发,可用来搭建和二次开发数字货币 ...
- HDU-1251 统计难题(我就是不用字典树)
统计难题 ?戳这里可以前往原题 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为 ...
- npm git 常用命令行 记录
1. 推出node命令行: 两次ctrl+C或者一次ctrl+D 退出终端:exit; 2.npm 常用 npm install <name> 安装包 npm install &l ...
- GitLab → 搭建中常遇的问题与日常维护
开心一刻 隔壁有一个80多岁的老大爷,昨天在小区的一棵树下发现一条黑色的蛇,冻僵了,大爷善心大发,就把蛇揣在了怀里,想给它一点温暖. 今天一大早看到大爷在树上挂了一个牌子,写到:不准随地大小便! 搭建 ...
- VBScript - 动态 Array 实现方法大全!
记录一些方法,关于 VBScript 中,动态 Array 的实现 ,也适用于 VBA, 很久以前,写 VBA 的时候,就觉得使用 Array 很不方便,因为大小固定, 当时想的是,要是 Array ...
- coding++:Semaphore—RateLimiter-漏桶算法-令牌桶算法
java中对于生产者消费者模型,或者小米手机营销 1分钟卖多少台手机等都存在限流的思想在里面. 关于限流 目前存在两大类,从线程个数(jdk1.5 Semaphore)和RateLimiter速率(g ...
- Linux的五种IO模型及同步和异步的区别
前置知识 缓存 I/O 缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O.在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓 ...
- [codevs3118]高精度除法<高精度>
题目链接:http://codevs.cn/problem/3118/ 为了做一道名为国王游戏的贪心,我跑来学习了高精度除法....相传,高精度除法是高精度四个基本运算最难的 但事实上,高精度除法可以 ...