一、安装依赖
CentOS
第一步:
第二步:
yum install freetype-devel libjpeg-devel libpng-devel
第三步:RPM包安装PIL
Windows
第一步:
第二步:
二、使用
Python生成随机验证码,需要使用PIL模块.
1. 创建图片
2. 创建画笔,用于在图片上画任意内容
3. 画点
4. 画线
5. 画圆
6. 写文本
7. 特殊字体文字
图片验证码
注意:字体文件下载,猛击这里
三、原理
![]()
![]()
from django.shortcuts importrender,HttpResponsefrom django.http importJsonResponsefrom django.contrib importauthdeflogin(request):#if request.method=="POST":
ifrequest.is_ajax():
user=request.POST.get("user")
pwd=request.POST.get("pwd")
validcode=request.POST.get("validcode") #获取用户输入的验证码
#Ajax请求返回一个字典
response={"user":None,"err_msg":""}if validcode.upper() == request.session.get("keep_str").upper(): #判断验证码是否对
user_obj=auth.authenticate(username=user,password=pwd)ifuser_obj:
response["user"]=userelse:
response['err_msg']="用户名或者密码错误!"
else:
response["err_msg"]="验证码错误!"
returnJsonResponse(response)else:return render(request, "login.html")from PIL importImage, ImageDraw, ImageFontfrom io importBytesIOimportrandomdefget_valid_img(request):defget_random_color():return (random.randint(0,255),random.randint(0,255),random.randint(0,255))
img= Image.new("RGB", (350, 38), get_random_color()) #新建一个图片对象
draw = ImageDraw.Draw(img) #根据图片对象新建一个文本对象
font = ImageFont.truetype("static/font/kumo.ttf", 32) #字体对象
keep_str= "" #验证码
for i in range(6):
random_num= str(random.randint(0, 9)) #随机数字
random_lowalf = chr(random.randint(97, 122)) #随机小写字母
random_upperalf = chr(random.randint(65, 90)) #随机大写字母
random_char =random.choice([random_num,random_lowalf,random_upperalf])
draw.text((i*30+50,0),random_char, get_random_color(), font=font) #在图片上写入文本
keep_str +=random_char#width = 350
#height = 38
#在验证码图片上随机加10条线
#for i in range(10):
#x1 = random.randint(0,width)
#x2 = random.randint(0,width)
#y1 = random.randint(0,height)
#y2 = random.randint(0,height)
#draw.line((x1,y1,x2,y2),fill=get_random_color())
# #在验证码图片上随机加50个点
#for i in range(50):
#draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
#x = random.randint(0, width)
#y = random.randint(0, height)
#draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())
#写与读
f = BytesIO() #创建一块内存空间
img.save(f, "png") #将图片保存到内存中
data = f.getvalue() #读取图片
#将验证码存在各自的session中
request.session['keep_str'] =keep_strreturn HttpResponse(data)
views.py(包含验证码的创建和检验)
![]()
![]()
Title
登录页面
$.ajax({
url:"",
type:"post",
data:{
user:$("#user").val(),
pwd:$("#pwd").val(),
validcode:$("#validcode").val(),
csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()
},
success:function (response) {if(response.user){//登录成功
location.href="http://www.luffycity.com"}else{//登录失败
$(".error").html(response.err_msg).css("color","red")
}
}
})
})//验证码刷新
$("#img").click(function () {
this.src+="?"})
login.html(包含ajax请求提交数据和验证码的刷新)
1、当用户访问 http://127.0.0.1:8000/login/ 时,Python自动生成一张图片输入到页面(即:验证码),并将图片上的文字内容保存在 Session中(即:request.session["CheckCode"] = '验证码的文字内容')。
2、用户输入用户名密码,点击登陆时:
首先,检查用户输入的 验证码 是否和Session中保存的验证码相同
然后,检查用户输入的 用户名 和 密码是否正确
使用checkcode示例:
1、生成验证码图片
session['CheckCode'] = code
2、看图片,输入图片上的内容
3、用户输入的值和session['CheckCode']进行比较
4、用户名和密码的验证
![]()
![]()
1 views.py2
3 importio4 importjson5 from django.shortcuts importHttpResponse, redirect, render6 from web.forms.account importSendMsgForm, RegisterForm, LoginForm7 from web importmodels8 from backend.utils importcheck_code as CheckCode9 from backend.utils.response importBaseResponse10 defcheck_code(request):11 """
12 获取验证码13 :param request:14 :return:15 """
16 stream =io.BytesIO()17 #创建随机字符 code
18 #创建一张图片格式的字符串,将随机字符串写到图片上
19 img, code =CheckCode.create_validate_code()20 img.save(stream, "PNG")21 #将字符串形式的验证码放在Session中
22 request.session["CheckCode"] =code23 returnHttpResponse(stream.getvalue())24 deflogin(request):25 """
26 用户登陆27 :param request:28 :return:29 """
30 rep =BaseResponse()31 form =LoginForm(request.POST)32 ifform.is_valid():33 _value_dict =form.clean()34 if _value_dict['code'].lower() != request.session["CheckCode"].lower():35 rep.message = {'code': [{'message': '验证码错误'}]}36 return HttpResponse(json.dumps(rep.__dict__))37 #验证码正确
38 from django.db.models importQ39
40 con =Q()41 q1 =Q()42 q1.connector = 'AND'
43 q1.children.append(('email', _value_dict['user']))44 q1.children.append(('password', _value_dict['pwd']))45
46 q2 =Q()47 q2.connector = 'AND'
48 q2.children.append(('username', _value_dict['user']))49 q2.children.append(('password', _value_dict['pwd']))50
51 con.add(q1, 'OR')52 con.add(q2, 'OR')53
54 obj =models.UserInfo.objects.filter(con).first()55 if notobj:56 rep.message = {'user': [{'message': '用户名邮箱或密码错误'}]}57 return HttpResponse(json.dumps(rep.__dict__))58
59 request.session['is_login'] =True60 request.session['user_info'] = {'nid': obj.nid, 'email': obj.email, 'username': obj.username}61 rep.status =True62 else:63 error_msg =form.errors.as_json()64 rep.message =json.loads(error_msg)65
66 return HttpResponse(json.dumps(rep.__dict__))67
68
69
70 html71
72
73
74
75
76
77
82
85
88
91
92
93
94 ![验证码]()
95
96
97
98
102
103
104 登陆
105
106 ![]()
107 正在登陆
108
109
110
111
112
113 function ChangeCode(ths) {114 ths.src += '?';115 }116
117
118
119
120 /*
121 点击注册按钮122 */
123 function SubmitRegister(ths){124 $('#register_error_summary').empty();125 $('#model_register .inp .error').remove();126
127 $(ths).children(':eq(0)').addClass('hide');128 $(ths).addClass('not-allow').children(':eq(1)').removeClass('hide');129
130 var post_dict ={};131 $('#model_register input').each(function(){132 post_dict[$(this).attr("name")] =$(this).val();133 });134
135 $.ajax({136 url: '/register/',137 type: 'POST',138 data: post_dict,139 dataType: 'json',140 success: function(arg){141 if(arg.status){142 window.location.href = '/index';143 }else{144 $.each(arg.message, function(k,v){145 //s
146 var tag = document.createElement('span');147 tag.className = 'error';148 tag.innerText = v[0]['message'];149 $('#model_register input[name="'+ k +'"]').after(tag);150 })151 }152 }153 });154
155 $(ths).removeClass('not-allow').children(':eq(1)').addClass('hide');156 $(ths).children(':eq(0)').removeClass('hide');157 }
View Code