django中怎么添加验证码(2023年最新整理)

高手们在线求帮请分析下,django中怎么添加验证码(2023年最新整理)
最新回答
星星泡饭

2024-10-12 07:40:55

导读:今天首席CTO笔记来给各位分享关于django中怎么添加验证码的相关内容,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

python怎么批量提交验证码

现在的网页中,为了防止机器人提交表单,图片验证码是很常见的应对手段之一。这里就不详细介绍了,相信大家都遇到过。

现在就给出用Python的PIL库实现验证码图片的代码。代码中有详细注释。

#!/usr/bin/envpython

#coding=utf-8

importrandom

fromPILimportImage,ImageDraw,ImageFont,ImageFilter

_letter_cases="abcdefghjkmnpqrstuvwxy"#小写字母,去除可能干扰的i,l,o,z

_upper_cases=_letter_cases.upper()#大写字母

_numbers=''.join(map(str,range(3,10)))#数字

init_chars=''.join((_letter_cases,_upper_cases,_numbers))

defcreate_validate_code(size=(120,30),

chars=init_chars,

img_type="GIF",

mode="RGB",

bg_color=(255,255,255),

fg_color=(0,0,255),

font_size=18,

font_type="ae_AlArabiya.ttf",

length=4,

draw_lines=True,

n_line=(1,2),

draw_points=True,

point_chance=2):

'''

@todo:生成验证码图片

@paramsize:图片的大小,格式(宽,高),默认为(120,30)

@paramchars:允许的字符集合,格式字符串

@paramimg_type:图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG

@parammode:图片模式,默认为RGB

@parambg_color:背景颜色,默认为白色

@paramfg_color:前景色,验证码字符颜色,默认为蓝色#0000FF

@paramfont_size:验证码字体大小

@paramfont_type:验证码字体,默认为ae_AlArabiya.ttf

@paramlength:验证码字符个数

@paramdraw_lines:是否划干扰线

@paramn_lines:干扰线的条数范围,格式元组,默认为(1,2),只有draw_lines为True时有效

@paramdraw_points:是否画干扰点

@parampoint_chance:干扰点出现的概率,大小范围[0,100]

@return:[0]:PILImage实例

@return:[1]:验证码图片中的字符串

'''

width,height=size#宽,高

img=Image.new(mode,size,bg_color)#创建图形

draw=ImageDraw.Draw(img)#创建画笔

defget_chars():

'''生成给定长度的字符串,返回列表格式'''

returnrandom.sample(chars,length)

defcreate_lines():

'''绘制干扰线'''

line_num=random.randint(*n_line)#干扰线条数

foriinrange(line_num):

#起始点

begin=(random.randint(0,size[0]),random.randint(0,size[1]))

#结束点

end=(random.randint(0,size[0]),random.randint(0,size[1]))

draw.line([begin,end],fill=(0,0,0))

defcreate_points():

'''绘制干扰点'''

chance=min(100,max(0,int(point_chance)))#大小限制在[0,100]

forwinxrange(width):

forhinxrange(height):

tmp=random.randint(0,100)

iftmp100-chance:

draw.point((w,h),fill=(0,0,0))

defcreate_strs():

'''绘制验证码字符'''

c_chars=get_chars()

strs='%s'%''.join(c_chars)#每个字符前后以空格隔开

font=ImageFont.truetype(font_type,font_size)

font_width,font_height=font.getsize(strs)

draw.text(((width-font_width)/3,(height-font_height)/3),

strs,font=font,fill=fg_color)

return''.join(c_chars)

ifdraw_lines:

create_lines()

ifdraw_points:

create_points()

strs=create_strs()

#图形扭曲参数

params=[1-float(random.randint(1,2))/100,

0,

0,

0,

1-float(random.randint(1,10))/100,

float(random.randint(1,2))/500,

0.001,

float(random.randint(1,2))/500

]

img=img.transform(size,Image.PERSPECTIVE,params)#创建扭曲

img=img.filter(ImageFilter.EDGE_ENHANCE_MORE)#滤镜,边界加强(阈值更大)

returnimg,strs

if__name__=="__main__":

code_img=create_validate_code()

code_img.save("validate.gif","GIF")

最后结果返回一个元组,第一个返回值是Image类的实例,第二个参数是图片中的字符串(比较是否正确的作用)。

最后结果返回一个元组,第一个返回值是Image类的实例,第二个参数是图片中的字符串(比较是否正确的作用)。

需要提醒的是,如果在生成ImageFont.truetype实例的时候抛出IOError异常,有可能是运行代码的电脑没有包含指定的字体,需要下载安装。

生成的验证码图片效果:

这时候,细心的同学可能要问,如果每次生成验证码,都要先保存生成的图片,再显示到页面。这么做让人太不能接受了。这个时候,我们需要使用python内置的StringIO模块,它有着类似file对象的行为,但是它操作的是内存文件。于是,我们可以这么写代码:

try:

importcStringIOasStringIO

exceptImportError:

importStringIO

mstream=StringIO.StringIO()

img=create_validate_code()[0]

img.save(mstream,"GIF")

这样,我们需要输出的图片的时候只要使用“mstream.getvalue()”即可。比如在Django里,我们首先定义这样的url:

fromdjango.conf.urls.defaultsimport*

urlpatterns=patterns('example.views',

url(r'^validate/$','validate',name='validate'),

)

在views中,我们把正确的字符串保存在session中,这样当用户提交表单的时候,就可以和session中的正确字符串进行比较。

fromdjango.shortcutsimportHttpResponse

fromvalidateimportcreate_validate_code

defvalidate(request):

mstream=StringIO.StringIO()

validate_code=create_validate_code()

img=validate_code[0]

img.save(mstream,"GIF")

request.session['validate']=validate_code[1]

returnHttpResponse(mstream.getvalue(),"image/gif")

django验证码用returnrender_to_response('bb.html',{'news':buf.getvalue()})不能正常显示图片!

render_to_response('bb.html',{'news':(buf.getvalue(),'image/gif')})

这一句呢有些问题。bb.html模板形式返回结果。如果我没有理解错的话,只能返回html格式,也许可以返回css,js。但是原则上不能返回image格式。

另外你的bb.html里的内容是什么呢?是不是只有一句话呢?

如果是。可以这样。

r=render_to_response('bb.html',{'news':(buf.getvalue(),'image/gif')})

然后引用r,试图改写它的Content-Type为'image/gif'

也许可以成功。只是也许。

Java如何实现验证码验证功能

Java如何实现验证码验证功能呢?日常生活中,验证码随处可见,他可以在一定程度上保护账号安全,那么他是怎么实现的呢?

Java实现验证码验证功能其实非常简单:用到了一个Graphics类在画板上绘制字母,随机选取一定数量的字母随机生成,然后在画板上随机生成几条干扰线。

首先,写一个验证码生成帮助类,用来绘制随机字母:

import?java.awt.Color;

import?java.awt.Font;

import?java.awt.Graphics;

import?java.awt.image.BufferedImage;

import?java.io.IOException;

import?java.io.OutputStream;

import?java.util.Random;

import?javax.imageio.ImageIO;

public?final?class?GraphicHelper?{

/**

*?以字符串形式返回生成的验证码,同时输出一个图片

*

*?@param?width

*????????????图片的宽度

*?@param?height

*????????????图片的高度

*?@param?imgType

*????????????图片的类型

*?@param?output

*????????????图片的输出流(图片将输出到这个流中)

*?@return?返回所生成的验证码(字符串)

*/

public?static?String?create(final?int?width,?final?int?height,?final?String?imgType,?OutputStream?output)?{

StringBuffer?sb?=?new?StringBuffer();

Random?random?=?new?Random();

BufferedImage?image?=?new?BufferedImage(width,?height,?BufferedImage.TYPE_INT_RGB);

Graphics?graphic?=?image.getGraphics();

graphic.setColor(Color.getColor("F8F8F8"));

graphic.fillRect(0,?0,?width,?height);

Color[]?colors?=?new?Color[]?{?Color.BLUE,?Color.GRAY,?Color.GREEN,?Color.RED,?Color.BLACK,?Color.ORANGE,

Color.CYAN?};

//?在?"画板"上生成干扰线条?(?50?是线条个数)

for?(int?i?=?0;?i??50;?i++)?{

graphic.setColor(colors[random.nextInt(colors.length)]);

final?int?x?=?random.nextInt(width);

final?int?y?=?random.nextInt(height);

final?int?w?=?random.nextInt(20);

final?int?h?=?random.nextInt(20);

final?int?signA?=?random.nextBoolean()???1?:?-1;

final?int?signB?=?random.nextBoolean()???1?:?-1;

graphic.drawLine(x,?y,?x?+?w?*?signA,?y?+?h?*?signB);

}

//?在?"画板"上绘制字母

graphic.setFont(new?Font("Comic?Sans?MS",?Font.BOLD,?30));

for?(int?i?=?0;?i??6;?i++)?{

final?int?temp?=?random.nextInt(26)?+?97;

String?s?=?String.valueOf((char)?temp);

sb.append(s);

graphic.setColor(colors[random.nextInt(colors.length)]);

graphic.drawString(s,?i?*?(width?/?6),?height?-?(height?/?3));

}

graphic.dispose();

try?{

ImageIO.write(image,?imgType,?output);

}?catch?(IOException?e)?{

e.printStackTrace();

}

return?sb.toString();

}

}?

接着,创建一个servlet,用来固定图片大小,以及处理验证码的使用场景,以及捕获页面生成的验证码(捕获到的二维码与用户输入的验证码一致才能通过)。

import?java.io.OutputStream;

import?javax.servlet.ServletException;

import?javax.servlet.annotation.WebServlet;

import?javax.servlet.http.HttpServlet;

import?javax.servlet.http.HttpServletRequest;

import?javax.servlet.http.HttpServletResponse;

import?javax.servlet.http.HttpSession;

@WebServlet(urlPatterns?=?"/verify/regist.do"?)

public?class?VerifyCodeServlet?extends?HttpServlet?{

private?static?final?long?serialVersionUID?=?3398560501558431737L;

@Override

protected?void?service(HttpServletRequest?request,?HttpServletResponse?response)

throws?ServletException,?IOException?{

//?获得?当前请求?对应的?会话对象

HttpSession?session?=?request.getSession();

//?从请求中获得?URI?(?统一资源标识符?)

String?uri?=?request.getRequestURI();

System.out.println("hello?:?"?+?uri);

final?int?width?=?180;?//?图片宽度

final?int?height?=?40;?//?图片高度

final?String?imgType?=?"jpeg";?//?指定图片格式?(不是指MIME类型)

final?OutputStream?output?=?response.getOutputStream();?//?获得可以向客户端返回图片的输出流

//?(字节流)

//?创建验证码图片并返回图片上的字符串

String?code?=?GraphicHelper.create(width,?height,?imgType,?output);

System.out.println("验证码内容:?"?+?code);

//?建立?uri?和?相应的?验证码?的关联?(?存储到当前会话对象的属性中?)

session.setAttribute(uri,?code);

System.out.println(session.getAttribute(uri));

}

}?

接着写一个HTML注册页面用来检验一下:

html

head

meta?charset="UTF-8"

title注册/title

link?rel="stylesheet"?href="styles/general.css"

link?rel="stylesheet"?href="styles/cell.css"

link?rel="stylesheet"?href="styles/form.css"

script?type="text/javascript"?src="js/ref.js"/script

style?type="text/css"?

.logo-container?{

margin-top:?50px?;

}

.logo-container?img?{

width:?100px?;

}

.message-container?{

height:?80px?;

}

.link-container?{

height:?40px?;

line-height:?40px?;

}

.link-container?a?{

text-decoration:?none?;

}

/style

/head

body

div?class="container?form-container"

form?action="/wendao/regist.do"?method="post"

div?class="form"?!--?注册表单开始?--

div?class="form-row"

span?class="cell-1"

i?class="fa?fa-user"/i

/span

span?class="cell-11"?style="text-align:?left;"

input?type="text"?name="username"?placeholder="请输入用户名"

/span

/div

div?class="form-row"

span?class="cell-1"

i?class="fa?fa-key"/i

/span

span?class="cell-11"?style="text-align:?left;"

input?type="password"?name="password"?placeholder="请输入密码"

/span

/div

div?class="