开发者社区> 狼人2007> 正文

艾伟:较为周全的Asp.net提交验证方案(Session版)

简介: 此前我介绍了使用数据库实现的提交验证方案,一些朋友怀疑其效率不佳,认为Session是更好的方案。 的确使用Session也不会消耗太多内存,而且如今内存白菜价,最不济就随手买个2G的插上也就够了,所以我将在此写下Session版的实现提要,其余细节参考前篇。
+关注继续查看

此前我介绍了使用数据库实现的提交验证方案,一些朋友怀疑其效率不佳,认为Session是更好的方案。

的确使用Session也不会消耗太多内存,而且如今内存白菜价,最不济就随手买个2G的插上也就够了,所以我将在此写下Session版的实现提要,其余细节参考前篇。

实现方案简述:

Session中存储一个哈希表用以记录该用户的每一条验证信息,哈希表的键为验证信息的过期时间,值为验证码的明文。

过期时间使用ViewState存储,以发给客户端,并在提交时获取,以读取对应的验证码明文。

传给验证码生成页面的ID参数是经ToFileTime()方法转换的过期时间,验证码生成页获取到此参数后进行逆转换,再读取对应的验证码明文以生成显示。

代码讲解:

先建立一个静态类,名为“提交验证”,将用于存储验证信息的Session变量封装为一个属性:

///

/// 验证信息表

///

static Hashtable 验证信息

{

    get

    {

        return Core.函数库.网络.Session["验证信息"] as Hashtable;

    }

    set

    {

        Core.函数库.网络.Session["验证信息"] = value;

    }

}

清理方法,用于将过期的数据清除:

///

/// 清理所有过期的验证信息

///

public static void 清理()

{

    if (验证信息 == null || 验证信息.Count < 5) return;

    foreach (DictionaryEntry f in (Hashtable)验证信息.Clone())

    {

        if ((DateTime)f.Key < DateTime.Now) 验证信息.Remove(f);

    }

}

小于5条验证信息则忽略。

克隆一个验证信息表供foreach使用,如果使用原表循环的话,直接移除内容会改变表长度,从而引发异常。

添加方法:

///

/// 添加一个新的验证信息。

///

/// 验证码">要保存的验证码

/// 过期时间差值">用于计算过期时间,单位为分钟

/// 过期时间戳

public static DateTime 添加(string 验证码, byte 过期时间差值)

{

    清理();

    var 过期时间 = DateTime.Now.AddMinutes(过期时间差值);

    if (验证信息 == null) 验证信息 = new Hashtable();

    验证信息.Add(过期时间, 验证码);

    return 过期时间;

}

在添加前进行过期信息清理工作。

获取、验证、移除方法:

///

/// 根据过期时间戳获取对应的验证码

///

/// 过期时间戳">验证信息过期时间戳

/// 验证码明文

public static string 获取(DateTime 过期时间戳)

{

    return 验证信息[过期时间戳] as string;

}

 

///

/// 验证用户输入的验证码是否正确

///

/// 过期时间戳">验证信息过期时间戳

/// 验证码">用户输入的验证码

/// 返回错误信息,如验证成功则返回null

public static string 验证(DateTime 过期时间戳, string 验证码)

{

    if (过期时间戳 < DateTime.Now) return "验证信息已过期";

    var 验证码明文 = 获取(过期时间戳);

    if (验证码明文 == null) return "验证信息无效或已过期";

    else if (验证码明文.ToLower() != 验证码.ToLower()) return "验证码错误";

    else return null;

}

 

///

/// 根据过期时间戳移除对应的验证信息

///

/// 过期时间戳">验证信息过期时间戳

public static void 移除(DateTime 过期时间戳)

{

    验证信息.Remove(过期时间戳);

}

使用方法:

使用时在页面上封装一个基于ViewState属性:

///

/// 时间戳属性,基于ViewState

///

public DateTime? 时间戳

{

    get

    {

        return ViewState["时间戳"] as DateTime?;

    }

    set

    {

        ViewState["时间戳"] = value;

    }

}

然后在load事件中调用:

protected void Page_Load(object sender, EventArgs e)

{

    if (!IsPostBack)

    {

        时间戳 = 提交验证.添加();

        Image1.ImageUrl = "~/VerifyImage.aspx?ID=" + 时间戳.Value.ToFileTime();

    }

}

(无参数的“添加”方法是我实现的一个适配器封装方法,采用默认的过期时间设置,随机生成验证码)

提交时的调用:

protected void Button1_Click(object sender, EventArgs e)

{

    var s = 提交验证.验证(时间戳.Value, TextBox1.Text);

    if (s == null)

    {

        CustomValidator1.IsValid = true;

 

        //提交...

 

        提交验证.移除(时间戳.Value);

    }

    else

    {

        CustomValidator1.IsValid = false;

        CustomValidator1.ErrorMessage = s;

    }

}

提示:

验证码生成时,建议只采用这些字符:2345678abcdefghijkmnprstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ

这里放弃了一些容易产生视觉混淆的字符,比如1Il0Oo,减少用户挠墙、砸电脑的可能。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
7638 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
13829 0
.net网站建设页面提交后css失效的问题
问题描述:.net网站建设在提交后出现css部分失效,如div位置,字体大小。问题解决:原因是,过去的提示语句我们一律使用了Response.write("alert("***")"),用了.write输出 js脚本.alert等破坏了css 加载。
913 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
13666 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
18233 0
+关注
狼人2007
个人对技术的追求:代码少而精捍;思路清晰美观;可扩展好维护;技术驱动商业; 人生格言:只要你有信念,有追求,并且坚持,那你一定比随波逐流,行得远行得正...
3526
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载