一、安装依赖
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
78 用户名登陆
79 |
80 邮箱登陆
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 一个月内自动登录
100 忘记密码?
101
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 }