使用C#登录带验证码的网站
我在上一篇文章中已经讲解了一般网站的登录原来和C#的登录实现,很多人问到对于使用了验证码的网站该怎么办,这里我就讲讲验证码的原理和对应的登录方法。
验证码的由来
几年前,大部分网站、论坛之类的是没有验证码的,因为对于一般用户来说验证码只是增加了用户的操作,降低了用户的体验。但是后来各种灌水机器人、投票机器人、恶意注册机器人层出不穷,大大增加了网站的负担同时也给网站数据库带来了大量的垃圾数据。为了防止各种机器人程序的破坏,于是程序员想出了只有人眼能够识别的,程序不容易识别的验证码!
验证码是一个图片,将字母、数字甚至汉字作为图片的内容,这样一张图片中的内容用人眼很容易识别,而程序将无法识别。在进行数据库操作之前(比如登录验证、投票、发帖、回复、注册等等)程序首先验证客户端提交的验证码是否与图片中的内容相同,如果相同则进行数据库操作,不同则提示验证码错误,不进行数据库操作。这样各种机器人程序就被拒之门外了!
但是随着计算机科学的发展,模式识别等技术越来越成熟,于是编写机器人程序的家伙可以通过程序将直接写在图片中的内容识别出来,然后提交到服务器,这样验证码将形同虚设。为了防止机器人程序的识别,验证码的图片生成也不断在发展,加入干扰点、干扰线,文字变形、变换角度位置,颜色不同……各种防止计算机识别的技术也应用到验证码中。就在这两种技术的竞争中,于是便形成了我们现在看到的验证码,已经有很多人在抱怨“这是什么验证码哦,人眼都分辨不清楚是什么”,一切也是无奈。
验证码的使用
验证码是针对各种机器人程序的,所以验证码图片中的内容是不能存放在Cookie、HTML和URL中的,如果看到一个验证码图片的URL是http://xxxxxx.com/Expwd.aspx?code=1af8 而验证码图片中的内容就是1af8那将是十分可笑的事情。同时,如果通过抓包发现了Cookie中保存了验证码的值或者查看HTML时看到了形如:<input type="hidden" id="exPwd" name="exPwd" value="1af8"/>这样将验证码的内容放在隐藏元素中也是不可思议的。对于这些行为,显然是这个程序员不知道验证码是拿来干什么的,只是别人的网站上有验证码,与自己的网站也弄一个来赶时髦。另外还有一种好笑的是验证码看上去像是验证码,结果看HTML代码居然不是一个图片,而是一个<span>1</span><span>a</span><span>f</span><span>8</span>。大家不要不以为然,以上这几种情况还真是我现实生活中遇到过的,当年写投票机器人的时候遇到这种情况我最高兴了!!!
验证码的内容必须保存在服务器端,一般我们可以将随机生成的验证码的内容放入Session中,用户提交的时候将提交的内容与Session中的验证码进行比较判断。在生成验证码的页面后台代码可以写为:
protected void Page_Load(object sender, EventArgs e)
{
string checkCode = CreateCode();
Session["CheckCode"] = checkCode;
CreateImage(checkCode);
}
比如在登录进行验证的时候可以写为:
protected void btnLogin_Click(object sender, ImageClickEventArgs e)
{
if (Session["CheckCode"] == null)
{
UIHelper.Alert(Page, "验证码已过期,请重新输入");
return;
}
if (Session["CheckCode"].ToString().ToLower() != txbCode.Text.ToLower())//验证码忽略大小写
{
UIHelper.Alert(Page, "验证码错误");
return;
}
//数据库验证……
}
使用C#登录带验证码的网站
前面我们已经对整个验证码的原理和使用有了基本的了解,现在言归正传,讲讲如何登录带验证码的网站。这里我们以CSDN的登录为例。
1.在IE中正常登录一次并把登录时候的数据包抓下来。
2.分析其中的登录原理如下:
1)请求http://passport.csdn.net/UserLogin.aspx页面,与服务器建立会话,服务器返回一个SessionID在HTTP的Header中,如下,其他内容我们可以忽略。
ASP.NET_SessionId=ydebagnqgiiixi2dvihfw355; path=/; HttpOnly,ABCDEF=; domain=csdn.net; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,QWERTOP=; domain=csdn.net; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,activeUserName=Guest; domain=csdn.net; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,UserName=Guest; domain=csdn.net; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,PName=; domain=csdn.net; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,ClientKey=; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,userid=0; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,ClientKey=933ffb09-5096-4fbb-b90f-5f0bff335b41; path=/
2)该页面返回的HTML中有一个<input type="hidden" name="ClientKey" value="a50b14fa-2a75-4364-bbeb-3b498b72aa46" />这个值在登录提交时也需要,所以需要从HTML代码中分离出来。
3)将该SessionID作为Cookie的内容发送到验证码生成的页面http://passport.csdn.net/ShowExPwd.aspx 该页面将返回一个图片的二进制流。
4)将返回的二进制流转换为图片并呈现给用户。
Image img = new Bitmap(
Http.GetStreamByBytes("http://passport.csdn.net" , "http://passport.csdn.net/ShowExPwd.aspx", b,
aspcookie, out header));//获得验证码图片
this.pictureBox1.Image = img;
5)用户输入用户名、密码和验证码,然后和同前面分离出的ClientKey按如下的格式POST到http://passport.csdn.net/UserLogin.aspx进行验证。
__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwULLTE4NDgzMDI2NjcPFgIeCkZpbmlzaFN0YXloFgJmD2QWBAIBDxYCHgRUZXh0BQznlKjmiLfnmbvlvZVkAgIPZBYCAgMPZBYCAgEPFgIeB1Zpc2libGVoZBgBBR5fX0NvbnRyb2xzUmVxdWlyZVBvc3RCYWNrS2V5X18WAgUeY3RsMDAkQ1BIX0NvbnRlbnQkY2JfU2F2ZVN0YXRlBR1jdGwwMCRDUEhfQ29udGVudCRJbWFnZV9Mb2dpbr5SL%2FGtMqVCJ%2FCh4jH%2FXp4DhlVU&ctl00%24CPH_Content%24tb_LoginNameOrLoginEmail=studyzy&ctl00%24CPH_Content%24tb_Password=123&ctl00%24CPH_Content%24tb_ExPwd=wgssj&ClientKey=a50b14fa-2a75-4364-bbeb-3b498b72aa46&ctl00%24CPH_Content%24cb_SaveState=on&from=http%3A%2F%2Fhi.csdn.net%2Fmy.html&MailParameters=&MailParameters=&ctl00%24CPH_Content%24Image_Login.x=26&ctl00%24CPH_Content%24Image_Login.y=11
6)验证成功的话将返回包含用户信息(发帖数、积分、博客排名等等)的HTML,验证失败将返回具体的错误信息。
3.以上将CSDN的登录原理分析清楚了,那么接下来就是代码实现了,代码实现比较简单,我直接在上篇文章所使用的Demo代码上修改的,所以写的不是很漂亮,大家若有兴趣可以看看。/Files/studyzy/LoginCSDNDemo.rar
成功登录后如图:
现在当前用户已经成功登录了,那么接下来是要在CSDN上发表博客、论坛发帖只需要将当前的SessionID放入Cookie中,在提交时使用该Cookie即可。
使用C#登录带验证码的网站的更多相关文章
- php使用curl模拟登录带验证码的网站[开发篇]
需求是这样的,需要登录带验证码的网站,获取数据,但是不可能人为一直去记录数据,想通过自动采集的方式进行,如下是试验出来的结果代码!有需要的可以参考下! <?php namespace Home\ ...
- php使用curl模拟登录带验证码的网站
需求是这样的,需要登录带验证码的网站,获取数据,但是不可能人为一直去记录数据,想通过自动采集的方式进行,如下是试验出来的结果代码!有需要的可以参考下! <?php namespace Home\ ...
- 用HttpWebRequest提交带验证码的网站
using System; using System.Drawing; using System.IO; using System.Net; using System.Text; using Syst ...
- C# 利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站
原文:C# 利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站 我们经常会碰到需要程序模拟登录一个网站,那如果网站需要填写验证码的要怎样模拟登录呢?这篇文章 ...
- Java模拟登录带验证码的教务系统(原理详解)
一:原理 客户端访问服务器,服务器通过Session对象记录会话,服务器可以指定一个唯一的session ID作为cookie来代表每个客户端,用来识别这个客户端接下来的请求. 我们通过Chrome浏 ...
- [PHP自动化-进阶]002.CURL模拟登录带有验证码的网站
引言:继前文<模拟登录并采集数据>,大家似乎看不过瘾,这会再出一发,模拟实现带验证码网站的登录. 这篇文章主要介绍了PHP使用CURL实现对带有验证码的网站进行模拟登录的方法,可以帮助读者 ...
- Python爬虫模拟登录带验证码网站
问题分析: 1.爬取网站时经常会遇到需要登录的问题,这是就需要用到模拟登录的相关方法.python提供了强大的url库,想做到这个并不难.这里以登录学校教务系统为例,做一个简单的例子. 2.首先得明白 ...
- python模拟艺龙网登录带验证码输入
1.使用urllib与urllib2包 2.使用cookielib自动管理cookie 3.360浏览器F12抓信息 登录请求地址和验证码地址都拿到了如图 # -*- coding: utf-8 -* ...
- python2 登录带验证码的页面
#!/usr/bin/python#-*- coding: utf-8 -*- import os,json;import urllib,urllib2;import cookielib; #获取co ...
随机推荐
- MAC 安装jenkins
下载地址 : https://jenkins.io/zh/download/ 由于用dmg安装包去安装jenkins,Jenkins不会用本地的用户去构建,任何创建的文件都是“jenkins”用户所有 ...
- 【MEAN Web开发】CentOS 7 安装MongoDB 3.2.3
偶然得了一本书,AmosQ.Haviv 所著 <MEAN Web开发>.起初并不知道这啥东西,看了下目录发现正好有讲MongoDB而已.当时的项目正好需要做MongoDB的内容,之后这书就 ...
- 在Python中操作文件之truncate()方法的使用教程
在Python中操作文件之truncate()方法的使用教程 这篇文章主要介绍了在Python中操作文件之truncate()方法的使用教程,是Python入门学习中的基础知识,需要的朋友可以参考下 ...
- Optimal Value Functions and Optimal Policy
Optimal Value Function is how much reward the best policy can get from a state s, which is the best ...
- Win10.资料
1.Win10版本consumer editions和business editions有什么区别?(http://www.winwin7.com/JC/10722.html) 2.密钥 win10 ...
- PHPer面试指南-laravel 篇
简述 Laravel 的生命周期 Laravel 采用了单一入口模式,应用的所有请求入口都是 public/index.php 文件. 注册类文件自动加载器 : Laravel通过 composer ...
- noip2018考后反思之爆0
今年又被Han老师鞭尸了TAT noip普及组比齐同学考的都差,正在准备退役Orz 哎,算了,该放题解还是要放的:( 普及第一题我觉得没有放的必要还是放一下 Code: #include<ios ...
- pandas分组聚合案例
美国2012年总统候选人政治献金数据分析 导入包 import numpy as np import pandas as pd from pandas import Series,DataFrame ...
- 项目使用Kafka镜像报错处理记录:this server does not host this topic-partition
背景 项目使用docker swarm部署 服务之间使用消息中间件 kafka 通信 Kafka 使用 star 3.7k 的 wurstmeister/kafka:2.12-2.2.1 镜像 Zoo ...
- .net core 使用RSA获取私钥证书并签名
RSA在.NET Core的改动 以前我们使用RSA加密主要是使用RSACryptoServiceProvider这个类,在.NET Core中也有这个类,但是这个类并不支持跨平台,所以如果你是用这个 ...