【ASP.NET MVC】使用动软(四)(12)

一、筛选器类和Cookie实现路由

需解决的问题:

网站登录往往需要用户名+密码验证,为避免重复验证,一般采用Cookie 、Session等技术来保持用户的登录状态:

Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式

 从上解释可见,Cookie 比 Session 更简单,也不占用服务器的资源。

ActionFilterAttribute  +  Cookie 可以解决 以上问题:

首先,在工程中新建一个空目录(名称自取):

然后,在目录中添加一个类 UserCookie  负责对用户登录信息的Cookie相应操作:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
namespace ManageSysetm.Tools
{public class UserCookie{public static T JsonDeserialize<T>(string jsonString){return JsonConvert.DeserializeObject<T>(jsonString);}public static string ToJson(object obj){JsonSerializerSettings settings = new JsonSerializerSettings();settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;return JsonConvert.SerializeObject(obj);}public static void WriteCookie(Maticsoft.Model.user mod){            FormsAuthentication.SetAuthCookie(ToJson(mod), true, FormsAuthentication.FormsCookiePath);//把用户对象保存在票据里                FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(1, mod.userName, DateTime.Now, DateTime.Now.AddTicks(FormsAuthentication.Timeout.Ticks), false, ToJson(mod));//加密票据string hashTicket = FormsAuthentication.Encrypt(Ticket);HttpCookie userCookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashTicket);userCookie.Expires.AddHours(3);System.Web.HttpContext.Current.Response.Cookies.Add(userCookie);}public static Maticsoft.Model.user ReadCookie(){try{var cookie = System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; //的到Cookieif (cookie == null)return null;var ticket = FormsAuthentication.Decrypt(cookie.Value); //解密票据string str = ticket.UserData;return JsonDeserialize<Maticsoft.Model.user>(str);}catch{return null;}}public static void ReMoveCookie(){FormsAuthentication.SignOut();}}
}

 说明:

1、添加了序列化的Json处理函数,关于JSON可以参考前面的介绍;

2、读写Cookie:对输入的Model 序列化 (ToJson) 成字符串,然后写入票据,读的过程正好相反

再添加筛选器类:IsLogin  继承于 ActionFilterAttribute

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;namespace ManageSysetm.Tools
{public class IsLogin : ActionFilterAttribute{//当方法执行时       public override void OnActionExecuting(ActionExecutingContext filterContext){try{              var isLogin = UserCookie.ReadCookie();if (isLogin == null){filterContext.Result = new RedirectResult("/Home/login");                 }}catch{filterContext.Result = new RedirectResult("/Home/login");               }base.OnActionExecuting(filterContext);}//当方法执行完毕public override void OnActionExecuted(ActionExecutedContext filterContext){base.OnActionExecuted(filterContext);}}
}

逻辑比较简单:判断是否存在Cookie,不存在的时候或者异常时跳转到登录页面,否则正常通过。

二、使用

可以用“帽子”的方法来实现筛选:

 在默认的路由 Index上添加 筛选器 IsLogin ,则在该Action执行前先进行筛选器判断:取Cookie,没有则返回登录页面,否则正常进入Index 。

拓展:

既然可以添加 筛选器 IsLogin ,那么是否也可以添加  筛选器 IsAdmin (名称自取) ? ——这样可以根据不同用户角色筛选进入不同的页面。

当然是可以的,解决思路无非就是加入用户Cookie中身份的判断逻辑!

三、补充

数据表中用明文记录用户的密码是不可取的,一旦数据表被曝光后,用户的角色就能够被人使用。比如:数据库管理人员可以利用数据表中的用户名和密码直接进行用户角色登录!

解决方法是加密:(贴几个实用函数,可以放入某个工具类中)

 private static string Key{get { return @")O[NB]6,YF}+efcaj{+oESb9d8>Z'e9M"; }}private static string IV{get { return @"L+\~f4,Ir)b$=pkf"; }}public static string Encrypt(string pwd)//加密{byte[] bKey = Encoding.UTF8.GetBytes(Key);byte[] bIV = Encoding.UTF8.GetBytes(IV);byte[] byteArray = Encoding.UTF8.GetBytes(pwd);//将字符串转换为字节序列string encrypt = null;Rijndael aes = Rijndael.Create();using (MemoryStream mStream = new MemoryStream())//创建内存流对象{using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateEncryptor(bKey, bIV), CryptoStreamMode.Write))//创建加密流对象{cStream.Write(byteArray, 0, byteArray.Length);//向加密流中写入字节序列cStream.FlushFinalBlock();//将数据压入基础流,用缓冲区的当前状态更新基础数据源或储存库,随后清除缓冲区。encrypt = Convert.ToBase64String(mStream.ToArray());//从内存流中获取字节序列,并返回加密后的字符串}}aes.Clear();return encrypt;}public static string AESDecrypt(string encryptStr){byte[] bKey = Encoding.UTF8.GetBytes(Key);byte[] bIV = Encoding.UTF8.GetBytes(IV);byte[] byteArray = Convert.FromBase64String(encryptStr);string decrypt = null;Rijndael aes = Rijndael.Create();using (MemoryStream mStream = new MemoryStream()){using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateDecryptor(bKey, bIV), CryptoStreamMode.Write)){cStream.Write(byteArray, 0, byteArray.Length);cStream.FlushFinalBlock();decrypt = Encoding.UTF8.GetString(mStream.ToArray());}}aes.Clear();return decrypt;}

使用方法比较简单:string s= UserCookie.Encrypt(password);  //对密码加密处理

加密字符串,由此解决用户表密码信息的保护:

 PS:

验证的时候不需要解密,用户输入的密码加密 与 数据表中字段匹配一下即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/23978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

glide加载content://com.android.contacts图片源码粗略梳理

获取链路是这样的&#xff1b; UriLoader类里定义了协议头&#xff1a; 里面有个内部类StreamFactory&#xff1a; 通过StreamLocalUriFetcher类的loadResource方法获取InputStream然后把流转换成为图片&#xff1b; 在这里作个草稿笔记给自己看

数据安全治理实施办法

随着《数据安全法》和《个人信息保护法》陆续出台&#xff0c;各行业数据安全监管力度持续增强&#xff0c;数据安全合规成为企业数据安全治理体系建设的第一推动力。同时&#xff0c;企业普遍面临数据安全治理成本过高&#xff0c;对业务影响过大&#xff0c;实施路径不清晰等…

适配器模式(AdapterPattern)

适配器模式 适配器模式&#xff08;Adapter Pattern&#xff09;是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式&#xff0c;它结合了两个独立接口的功能。 优缺点 优点&#xff1a; 单一职责原则。你可以将接口或数据转换代码从程序主要业务逻辑中分…

Docker 安装 MySQL5.6

方法一、docker pull mysql 查找Docker Hub上的mysql镜像 #docker search mysql 这里我们拉取官方的镜像,标签为5.6 #docker pull mysql:5.6 &#xff08;第一次启动Docker-MySql主要是查看Docker里面MySQL的默认配置&#xff0c;数据位置&#xff0c;日志位置&#xff0c;配…

Arthas GC日志-JVM(十八)

上篇文章说jvm的实际运行情况。 Jvm实际运行情况-JVM&#xff08;十七&#xff09; Arthas介绍 因为arthas完全是java代码写的&#xff0c;我们直接用命令启动&#xff1a; Java -jar arthas-boot.jar 启动成功后&#xff0c;选择我们项目的进程。 进入我们可用dashboard…

使用ChatGPT编写技术文档

技术文档对于任何项目都是至关重要的&#xff0c;因为它确保所有利益相关者都在同一层面上&#xff0c;并允许有效的沟通和协作。创建详细而准确的技术文档可能既耗时又具有挑战性&#xff0c;特别是对于那些不熟悉主题或缺乏强大写作技巧的人来说。ChatGPT 是一个强大的人工智…

docker容器学习笔记1

docker容器是干什么用的 docker就是一个轻量级的虚拟机&#xff0c;是一个容器&#xff0c;隔离性好&#xff0c;能够确保环境的统一&#xff0c;有效利用系统资源&#xff0c;轻松迁移和拓展。简单的可以理解为容器就是一个小型功能齐全的虚拟机。 实际上是如何使用的呢&…

DNS部署与安全详解(上)

文章目录 一、DNS二、域名组成1. 域名组成概述2. 域名组成 三、监听端口四、DNS解析种类1. 按照查询方式分类&#xff1a;2. 按照查询内容分类&#xff1a; 五、DNS服务器搭建过程1. 先确保服务器的IP地址是固定的2. 安装DNS软件 一、DNS DNS全称Domain Name Service&#xff0…

大文件裁剪阿里云oss上传 plupload

亲测有效 home/include_upload_maxfile.jsp 效果如下 <% page language"java" import"java.util.*" pageEncoding"UTF-8"%> <%String path request.getContextPath();%><%page import"com.home.base.DBRow"%> &l…

求解n阶勒让德多项式的值

描述 用递归方法求n阶勒让德多项式的值&#xff0c;递归公式为&#xff1a; 在主函数中输入一个整数n和一个实数x&#xff0c;调用函数 legendre(n,x)&#xff0c;并输出其返回值。 输入 第一行输入一个整数n&#xff0c;表示阶数&#xff1b;第二行输入一个实数x。 输出 …

【机器学习】 贝叶斯理论的变分推理

许志永 一、说明 贝叶斯原理&#xff0c;站在概率角度上似乎容易解释&#xff0c;但站在函数立场上就不那么容易了&#xff1b;然而&#xff0c;在高端数学模型中&#xff0c;必须要在函数和集合立场上有一套完整的概念&#xff0c;其迭代和运算才能有坚定的理论基础。 二、贝叶…

Gson:解析JSON为复杂对象:TypeToken

需求 通过Gson&#xff0c;将JSON字符串&#xff0c;解析为复杂类型。 比如&#xff0c;解析成如下类型&#xff1a; Map<String, List<Bean>> 依赖&#xff08;Gson&#xff09; <dependency><groupId>com.google.code.gson</groupId><art…

MyBatis核心 - SqlSession如何通过Mapper接口生成Mapper对象

书接上文 MyBatis – 执行流程 我们通过SqlSession获取到了UserMapper对象&#xff0c;代码如下&#xff1a; // 获取SqlSession对象 SqlSession sqlSession sqlSessionFactory.openSession();// 执行查询操作 try {// 获取映射器接口UserMapper userMapper sqlSession.get…

vue SKU已知sku.tree算出sku.list类目值和id

已知sku.tree算出sku.list类目值和id <van-skuref"sku"v-model"showBase":close-on-click-overlay"closeOnClickOverlay":goods"skuData.goods_info":goods-id"skuData.goods_id":hide-stock"skuData.sku.hide_stoc…

数据结构---B树

目录标题 B-树的由来B-树的规则和原理B-树的插入分析B-树的插入实现准备工作find函数insert中序遍历 B-树的性能测试B-树的删除B树B树的元素插入B*树的介绍 B-树的由来 在前面的学习过程中&#xff0c;我们见过很多搜索结构比比如说顺序查找&#xff0c;二分查找&#xff0c;搜…

mac安装nacos,M1芯片

第一步&#xff0c;官网下载 》nacos官网 去github中下载对应的版本&#xff0c;本人下载的是1.4.1版本 在这儿选择其他的版本&#xff0c;下面这里选择 tar.gz 压缩包 解压后放到一个非中文的目录下&#xff0c;我选择在 user目录下面创建一个other目录&#xff0c;将使用的环…

[回馈]ASP.NET Core MVC开发实战之商城系统(五)

经过一段时间的准备&#xff0c;新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始&#xff0c;在之前的文章中&#xff0c;讲解了商城系统的整体功能设计&#xff0c;页面布局设计&#xff0c;环境搭建&#xff0c;系统配置&#xff0c;及首页【商品类型&#xff0c;ba…

freeswitch的mod_xml_curl模块动态获取dialplan

概述 freeswitch是一款简单好用的VOIP开源软交换平台。 mod_xml_curl模块支持从web服务获取xml配置&#xff0c;本文介绍如何动态获取dialplan配置。 环境 centos&#xff1a;CentOS release 7.0 (Final)或以上版本 freeswitch&#xff1a;v1.6.20 GCC&#xff1a;4.8.5…

小乌龟(TortoiseGit)连接GitLab

目录 &#x1f35f;写在前面 &#x1f35f;实验目标 &#x1f35f;安装gitlab &#x1f37f;1、安装依赖 &#x1f37f;2、下载清华gitlab包 &#x1f37f;3、安装gitlab &#x1f37f;4、修改配置文件 &#x1f37f;5、管理命令 &#x1f35f;访问gitlab &#x1f35f;界面设置…

【WebRTC---源码篇】(二:一)PeerConnection详解

Track的添加 上图是整体流程图 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(rtc::scoped_refptr<MediaStreamTrackInterface> track,const std::vector<std::string>& stream_ids) {RTC_DCHECK_RUN_ON(signal…