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

news2024/12/29 17:55:42

一、筛选器类和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]; //的到Cookie
                if (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.coloradmin.cn/o/836372.html

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

相关文章

EtherCAT转MODBUS RTU/RS485/232总线协议网关

产品功能 JM-ECT-RTU是一款EtherCAT从站功能的通讯网关。该产品主要功能是将EtherCAT网络和MODBUS-RTU网络连接起来。 JM-ECT-RTU网关连接到EtherCAT总线中作为从站使用&#xff0c;连接到MODBUS-RTU总线中作为主站或从站使用。 本网关产品将基于MODBUS 的设备或串行RS-232/…

10分钟理解React生命周期

前言 学习React&#xff0c;生命周期很重要&#xff0c;我们了解完生命周期的各个组件&#xff0c;对写高性能组件会有很大的帮助。 一、简介 React /riˈkt/ 组件的生命周期指的是组件从创建到销毁过程中所经历的一系列方法调用。这些方法可以让我们在不同的时刻执行特定的…

科班应届生,我选择来黑马提升技能!

不论是因为对未来的迷茫和焦虑&#xff0c;还是对生活的现状不满意&#xff0c;又或者是想完善自己的专业知识&#xff0c;亦或是跨界迎接新的挑战&#xff0c;都可以来黑马…… 学科 | JavaEE 校区 | 武汉 薪资 | 10k&#xff08;应届生&#xff09; 黑马程序员的学弟、学妹…

【方法】Excel表格如何拆分数据?

当需要把多个数据逐个填到Excel单元格的时候&#xff0c;我们可以利用Excel的数据拆分功能&#xff0c;可以节省不少时间。 小编以下面的数据为例&#xff0c;看看如何进行数据拆分。 首先&#xff0c;要选择数字所在的单元格&#xff0c;然后依次点击菜单栏中的“数据”>…

Django实现音乐网站 ⑹

使用Python Django框架制作一个音乐网站&#xff0c; 本篇主要是在添加编辑过程中对后台歌手功能优化及表模型名称修改、模型继承内容。 目录 表模型名称修改 模型继承 创建抽象基类 其他模型继承 更新表结构 歌手新增、编辑优化 表字段名称修改 隐藏单曲数和专辑数 姓…

Redis 单线程VS多线程

面试题 redis到底是单线程还是多线程&#xff1f;IO多路复用是什么&#xff1f;redis为什么快&#xff1f; Redis单线程 是什么 Redis的版本很多3.x、4.x、6.x&#xff0c;版本不同架构也是不同的&#xff0c;不限定版本问是否单线程也不太严谨。 1、版本3.x &#xff0c;最…

中外人工智能专家共话大语言模型与 AI 创新

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 智源社区活动&#xff0c;中外人工智能专家共话大语言模型与 AI 创新。 对谈书目&#xff1a; 《大模型时代》&#xff0c;龙志勇、黄雯 著&#xf…

.Net6 Web Core API --- Autofac -- AOP

目录 一、AOP 封装 二、类拦截 案例 三、接口拦截器 案例 AOP拦截器 可开启 类拦截器 和 接口拦截器 类拦截器 --- 只有方法标注 virtual 标识才会启动 接口拦截器 --- 所有实现接口的方法都会启动 一、AOP 封装 // 在 Program.cs 配置 builder.AddAOPExt();//自定义 A…

软件测试方案模板

第一章 概述 ​ 软件的错误是不可避免的&#xff0c;所以必须经过严格的测试。通过对本软件的测试&#xff0c;尽可能的发现软件中的错误&#xff0c;借以减少系统内部各模块的逻辑&#xff0c;功能上的缺陷和错误&#xff0c;保证每个单元能正确地实现其预期的功能。检测和排…

docker端口映射详解(随机端口、指定IP端口、随意ip指定端口、指定ip随机端口)

目录 docker端口映射详解 一、端口映射概述&#xff1a; 二、案例实验&#xff1a; 1、-P选项&#xff0c;随机端口 2、使用-p可以指定要映射到的本地端口。 Local_Port:Container_Port&#xff0c;任意地址的指定端口 Local_IP:Local_Port:Container_Port 映射到指定地…

亚马逊买家号付款异常被锁定是什么原因?怎么解决?

如果在亚马逊上&#xff0c;买家号出现付款异常&#xff0c;可能会导致账号被锁定或受限。这通常是为了保护消费者和卖家的利益&#xff0c;以及防范欺诈行为。 1、常见的买家号付款异常情况可能包括&#xff1a; 付款信息不一致&#xff1a;如果买家提供的付款信息与其账号信…

第三章 图论 No.2单源最短路之虚拟源点,状压最短路与最短路次短路条数

文章目录 1137. 选择最佳线路1131. 拯救大兵瑞恩1134. 最短路计数383. 观光 dp是特殊的最短路&#xff0c;是无环图&#xff08;拓扑图&#xff09;上的最短路问题 1137. 选择最佳线路 1137. 选择最佳线路 - AcWing题库 // 反向建图就行 #include <iostream> #include…

再续AM335x经典,米尔TI AM62x核心板上市,赋能新一代HMI

近十年来&#xff0c;AM335x芯片作为TI经典工业MPU产品&#xff0c;在工业处理器市场占据主流地位&#xff0c;其凭借GPMC高速并口、PRU协处理器等个性化硬件资源&#xff0c;在工业控制、能源电力、轨道交通、智慧医疗等领域广受用户欢迎。随着信息技术的快速发展&#xff0c;…

Java实现数据库表中的七种连接【Mysql】

Java实现数据库表中的七种连接【Mysql】 前言版权推荐Java实现数据库表中的七种连接左外连接右外连接其他连接 附录七种连接SQL测试Java测试转换方法类 Cla1类 Cla2类Cla3 最后 前言 2023-8-4 16:51:42 以下内容源自《【Mysql】》 仅供学习交流使用 版权 禁止其他平台发布时…

ARCGIS地理配准出现的问题

第一种。已有省级行政区矢量数据&#xff0c;在网上随便找一个相同省级行政区图片&#xff0c;利用地理配准工具给图片添加坐标信息。 依次添加省级行政区选择矢量数据、浙江省图片。 此时&#xff0c;图层默认的坐标系与第一个加载进来的省级行政区选择矢量数据的坐标系一致…

opencv基础40-礼帽运算(原始图像减去其开运算)cv2.MORPH_TOPHAT

礼帽运算是用原始图像减去其开运算图像的操作。礼帽运算能够获取图像的噪声信息&#xff0c;或者得到比原始图像的边缘更亮的边缘信息。 例如&#xff0c;图 8-22 是一个礼帽运算示例&#xff0c;其中&#xff1a; 左图是原始图像。中间的图是开运算图像。右图是原始图像减开运…

人工智能的最新进展:2024年将会发生什么?

文章目录 2024年AI最新发展2024年AI具体应用2024年AI的具体预测 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xff1a;全栈弄潮儿的个人社区 &#x1f4d9; 专栏地址&#…

滥⽤合法商⽤程序⽤以进⾏访问控制

背景 攻击对抗日益激烈的局势下&#xff0c;安全产品的围追堵截使得攻击者将目光逐渐转向合法工具的滥用。通过使用具有合法签名的应用程序进行访问控制可以有效提高攻击隐匿性&#xff0c;也对防守及检测提出新的挑战。本文以Vscode、AnyDesk、GotoAssist为例探索攻击者用于访…

海外热门地区/国家常见主体证件示例

海外热门地区/国家常见主体证件示例&#xff08;本页面内容较多&#xff0c;你可以通过CtrlF搜索&#xff09; Overseas Popular Areas / Countries Examples of Common certificates &#xff08;This page has more content, you can search by CtrlF&#xff09; 中国香港…

C++数据结构之平衡二叉搜索树(一)——AVL的实现(zig-zag/左右双旋/3+4重构)

目录 00.BBST——平衡二叉搜索树01.AVL树02.AVL的插入2.1单旋——zig 与 zag2.2插入节点后的单旋实例2.3手玩小样例2.4双旋实例2.5小结 03.AVL的删除3.1单旋删除3.2双旋删除3.3小结 04.34重构05.综合评价AVL5.1优点5.2缺点 00.BBST——平衡二叉搜索树 本文是介绍众多平衡二叉搜…