HttpHandler

Wesley13
• 阅读 195

 今天简单的做下HttpHandler的练习:只有登录用户才能下载images下地图片文件(Session中标识是否登录),如果用户没有登录则首先重定向到登录界面让用户登录,用户登录成功则跳转到下载列表页面,下载链接固定写好即可。如果登录用户是普通用户则在图片左上角加上“免费用试用”的字样。

1.首先建立名为UserAuthority的数据库,然后新建名为T_Users的表,如下所示

HttpHandler

Level字段是记录用户的下载权限(”0”为免费用户和“1“为收费用户)。ErrorTimes为记录用户错误登录次数。LastErrorTimes则为记录用户错误登录的时间(如果错误登录次数过多则会限制用户登录,防止恶意用户不断进行登录)

再进行操作之前,我现在T_Users表里录入些数据,如下:

HttpHandler

2.创建名为DataSetUser的强类型DataSet,然后将表T_Users拖到此文件里面

HttpHandler

其中,需要建立查询使用的SQL语句

(GetDataByID(@ID) :SELECT ID, UserName, Password, [Level], ErrorTimes, LastErrorTimes FROM dbo.T_Users
where ID=@ID

,GetDataByUserName :SELECT ID, UserName, Password, [Level], ErrorTimes, LastErrorTimes FROM dbo.T_Users
where UserName=@UserName

,IncErrorTimesById:Update T_Users set ErrorTimes=IsNULL(ErrorTimes,0)+1,LastErrorTimes=getDate() whereID=@ID

ResetErrorTimesById):UPDATE T_Users set ErrorTimes=0  where ID=@ID

3.建立所需页面。

   (1).Login.aspx

   HttpHandler

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using 用户权限下载.DAL.DataSetUserTableAdapters;

namespace 用户权限下载
{
    public partial class Login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {

try
            {
            T_UsersTableAdapter adapter = new T_UsersTableAdapter();
            var data = adapter.GetDataByUserName(TextBox1.Text);
            if (data.Count <= 0)
            {
                LabelErrorMsg.Text = "用户名不存在!";
                LabelErrorMsg.Visible = true;
            }
            var user = data.Single();//linq 时的Single方法,返回唯一一条数据,如果数据为0或者多条,则抛出异常,把程序的错误扼杀在摇篮中
            if (!user.IsErrorTimesNull() && !user.IsLastErrorTimesNull())
            {
                double timeSpan = (DateTime.Now - user.LastErrorTimes).TotalMinutes;//计算当前时间和上次时间之间的差得分钟数
                if (user.ErrorTimes > 5 && timeSpan < 30)
                {
                    LabelErrorMsg.Text = "您的输入错误次数过多,请再30分钟之后再尝试登录";//一旦被锁定就不告诉访问者密码是对还是错

LabelErrorMsg.Visible = true;
                    return;
                }
            }
            if (user.Password == TextBox2.Text)
            {
                Session["IsLoginornot"] = true;
                Session["UserID"] = user.ID;
                adapter.ResetErrorTimesById(user.ID);

string verCode = Session["Code"].ToString();
                LabelErrorMsg.Visible = false;
                    if (verCode != TextBox3.Text)
                    {
                        LabelVerCode.Text = "验证码错误";
                        LabelVerCode.Visible = true;
                       // return;
                    }
                    else
                    {
                        Response.Redirect("DownLoadList.htm");
                    }
                Response.Redirect("DownLoadList.htm");
            }
            else
            {

//int errorTimes=user.ErrorTimes+1;//可直接写到强类型DataSet那里
                LabelErrorMsg.Text = "密码错误,请重新输入";//注意数据库值为null的问题
                adapter.IncErrorTimesById(user.ID);//增加防暴力破解,重复错误五次,就锁定账户半个小时(错误次数,上次所悟时间)
                LabelErrorMsg.Visible= true;
            }
        }

 catch (Exception)
            {
            }
     }
}

 

 (2)图片下载页面 DownloadList.htm

  HttpHandler

  和此页面的HTML代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
 <a href="DownloadPic.ashx?FileName=1.jpg">One</a><br />
 <a href="DownloadPic.ashx?FileName=2.jpg">Two</a><br />
 <a href="DownloadPic.ashx?FileName=3.jpg">Three</a><br />
</body>
</html>

 

(3)如果用户还没登录,会提示登录并转到RedirectToLogin.htm

   HTML代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        var leftSeconds = 4;
        setInterval(function () {
            if (leftSeconds <= 0) {
                window.location.href = "Login.aspx";
            }
            document.getElementById("leftDiv").innerText = leftSeconds;
            leftSeconds--;
        }, 1000);
    
    </script>
</head>
<body>
   由于您还没登录,不能进行下一步操作,本页面在<div id="leftDiv">0</div>秒后跳转到登录页面<br/>
   <a href="Login.aspx">点击这里可以直接跳转到登录页面</a>
</body>
</html>

 

(4)建立图片下载的过程的代码(动态生成JPEG图片然后弹出对话框让用户下载,文件名为图片名),先建立名为DownloadPic.ashx 的文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using 用户权限下载.DAL.DataSetUserTableAdapters;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web.SessionState;

namespace 用户权限下载
{
    /// <summary>
    /// DownloadPic 的摘要说明
    /// </summary>
    public class DownloadPic : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            if (context.Session["IsLoginornot"] == null)
            {
                context.Response.Redirect("RedirectToLogin.htm");//跳转到RedirectToLogin页面,3秒后或直接点击进入Login.aspx页面
            }
            else
            {
                string filename = context.Request["FileName"];

                context.Response.ContentType = "images/JPEG";
                string encodeFileName = HttpUtility.UrlEncode(filename);
                context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename=\"{0}\"", encodeFileName));
                int userId = (int)context.Session["UserID"];
                T_UsersTableAdapter adapter = new T_UsersTableAdapter();
                var data = adapter.GetDataByID(userId);
                var user = data.Single();
                if (user.Level == 0)
                {
                    using (Bitmap bitmap = new Bitmap(context.Server.MapPath("images/") + filename))
                    {
                        using (Graphics g = Graphics.FromImage(bitmap))
                        {
                            g.DrawString("免费用户使用", new Font("宋体", 40), Brushes.Red, 0, 0);
                        }
                        bitmap.Save(context.Response.OutputStream, ImageFormat.Jpeg);
                    }
                }
                else//收费用户
                {
                    context.Response.WriteFile("images/" + filename);//有攻击漏洞,重复错误5次,就锁定账户半个小时。还有,避免DownloadPic.ashx?FileName=../DownloadPic.ashx.cs 的漏洞
                }

            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

 

4.增加验证码功能:

VerificationCode

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Drawing;

namespace 用户权限下载
{
    /// <summary>
    /// VerificationCode 的摘要说明
    /// </summary>
    public class VerificationCode : IHttpHandler, System.Web.SessionState.IRequiresSessionState 
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType="images/JPEG";

            using(Bitmap bitmap=new Bitmap(70,35))
            {
               using(Graphics g=Graphics.FromImage(bitmap))
               {
                   Random rand=new Random();
                   int code=rand.Next(1000,9999);
                   string strCode=Convert.ToString(code);
                   HttpContext.Current.Session["Code"]=strCode;
                   g.DrawString(strCode,new Font("宋体",20),Brushes.Red,0,0);
                   bitmap.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
               }
            }
         
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
点赞
收藏
评论区
推荐文章
马丁路德 马丁路德
1年前
小程序静默登录与维护自定义登录态
1.背景在小程序中,openid是一个用户对于一个小程序/公众号的标识,开发者可以通过这个标识识别出用户,就如同你的身份证一样。2.什么是静默登录?在普通的应用中,用户通过表单验证登录建立用户体系,这种常见的登录方式一般是通过登录页面表单进行登录,对用户来说是有感的。在小程序中,由于是基于微信,可以通过微信官方提供的API能力,使我们能够无感知得获取
_dolphin _dolphin
1年前
.net core Cookie的使用
缘起:  公司领导让我做一个测试的demo,功能大概是这样的:用户通过微信扫一扫登陆网站,如果用户登录过则直接进入主界面,否则就保留在登录界面。实现方法:  首先先把网站地址生成个二维码,在扫描二维码后去获取Cookie如果有值那么就证明登录过直接跳转到主界面,如果Cookie不存在用户通过登录记录的用户信息并保存到Cookie。什么是Cookie:  储存
Wesley13 Wesley13
1年前
CAS单点登录(一):单点登录与CAS理论介绍
一、什么是单点登录(SSO)  单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个,无须多次登录。  单点登录(SingleSignOn),简称为SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所
Wesley13 Wesley13
1年前
IOS 用户登录界面
导航AppDelegate.hAppDelegate.mViewController.hViewController.muserEnterView.xibAppDelegate.himport<UIKit/UIKit.h@class(http://my.oschina.net/liwenlong7758)View
Stella981 Stella981
1年前
Nodejs,Express利用内置的session实现登录控制
varfilterrequire('./lib/filter');判断是否已经登录如果登录了则过去,否则跳转到登录页exports.authorizefunction(req,res,next){if(!req.session.user_id){res.redi
Wesley13 Wesley13
1年前
Asp.Net Forms认证在移动平台中遇到的一个问题以及调查过程
我们项目的网站的移动版是基于Asp.Net平台开发的,用户登录也是基于Asp.Net的Forms认证,在整个开发和测试过程中没有发现任何客户登录异常,但是发布后断断续续有用户反映在登录页面登录成功后跳转主页后,主页并没有识别登录用户,也即是Form认证失败。Asp.Net的Form认证大家应该有所了解,其内部的机制就是把用户数据加密后保存在一个基于cook
Wesley13 Wesley13
1年前
java简单的用户登录界面+mysql
1.概述一个简单的swing登录界面,使用了简单的JDBC.如图:!在这里插入图片描述(https://imgblog.csdnimg.cn/20191210013512615.png)!在这里插入图片描述(https://imgblog.csdnimg.cn/20191210013543435.png)2.UI
Stella981 Stella981
1年前
Spring Security使用详解7(注销登录配置)
默认情况下,SpringSecurity提供了注销接口是/logout,访问这个接口即可注销当前登录用户并且自动跳转到登录页。如果需要修改注销接口,或者想在注销时做一些业务逻辑,或者注销后不是跳转到登录页而是返回一段JSON提示,只需在一些简单配置即可。七、注销登录配置1、样例代码首先修改SpringSecurit
Wesley13 Wesley13
1年前
Java 可以用已知帐号登录,且可以注册后登录的小程序
|需求说明1、写一个注册和登录功能,使用已知的帐号和密码可以直接登录,如果没有帐号,注册后可以用刚注册的帐号登录2、注册的时候,如果帐号已经存在,不能注册3、注册的时候,设置两次密码,如果两次密码设置得不同,不能注册4、登录的时候,密码输错三次,锁定帐号5、登录的时候,如果没有这个帐号,则提醒用户注册,注册后可以登录6、登录的时候
Stella981 Stella981
1年前
Django【十二】中间价
一前戏  我们在前面的课程中已经学会了给视图函数加装饰器来判断是用户是否登录,把没有登录的用户请求跳转到登录页面。我们通过给几个特定视图函数加装饰器实现了这个需求。但是以后添加的视图函数可能也需要加上装饰器,这样是不是稍微有点繁琐。  学完今天的内容之后呢,我们就可以用更适宜的方式来实现类似给所有请求都做相同操作的功能了二中间
Wesley13 Wesley13
1年前
mysql学习总结(三)
1.SQL注入     1)什么是sql注入:         例如:用户在网页进行登录操作时,输入数据库语句,导致网页的登录限制失效,不需要输入用户名和密码,用户可以输入语句就登录网页     2)出现sql注入的原因:        因为太相信用户的输入,导致我们在接收用户