最近有小伙伴提问:能否说下web验证的原理,感觉文字描述不清楚,于是就用代码简单的演示下:此代码是需要依赖:
sanic==19.9.0Pillow==7.0.0
![3f5fbb3485ecaeb39e4aebb22e55b1eb.png](https://i-blog.csdnimg.cn/blog_migrate/f124fdb8a2cbaeeda7dd05c4ccbee1d5.jpeg)
import randomimport stringimport uuidimport base64import platformfrom PIL import Image, ImageDraw,ImageFontfrom io import BytesIOfrom sanic import Sanicfrom sanic.response import HTTPResponse,textfrom sanic.views import HTTPMethodViewapp = Sanic()session = {}class VerifyCode: def __init__(self, numbers:int): """ 指定:生成的数量 """ self.number = numbers def draw_lines(self, draw, num, width, height): """划线""" x1 = random.randint(0, width / 2) y1 = random.randint(0, height / 2) x2 = random.randint(0, width) y2 = random.randint(height / 2, height) draw.line(((x1, y1), (x2, y2)), fill='black', width=1) def random_color(self): """随机颜色""" return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127)) def gene_text(self): """生成验证码""" return "".join(random.sample(string.ascii_letters+string.digits, self.number)) def get_verify_code(self): """ draw.text(): 文字的绘制,第一个参数指定绘制的起始点(文本的左上角所在位置),第二个参数指定文本内容,第三个参数指定文本的颜色,第四个参数指定字体(通过ImageFont类来定义) """ code = self.gene_text() width, height = 130, 30 im = Image.new("RGB", (width, height), "white") # 这里指定字体的路径 sysstr = platform.system() font = None if sysstr == "Windows": font = ImageFont.truetype("C:WINDOWSFontsSTXINGKA.TTF", 25) elif sysstr == "Darwin": font = ImageFont.truetype('/Library/Fonts/AppleMyungjo.ttf', 25) draw = ImageDraw.Draw(im) for item in range(self.number): draw.text((5+random.randint(-5,5)+23*item, 5+random.randint(-5, 5)), text=code[item], fill=self.random_color(), font=font) self.draw_lines(draw, self.number, width, height) return im, codeclass SimpleView(HTTPMethodView): body = """ 登录
{error}
验证码
![]()
验证
""" async def get(self, request): return self.response(error="") async def post(self, request): uuid = request.cookies.get("uuid", "1") verfy_code = request.form.get("code", "2").lower() code = session.get(uuid, "").lower() if code == verfy_code: return text('验证码正确') return self.response(error='') def response(self, error): im, code = VerifyCode(5).get_verify_code() buf = BytesIO() im.save(buf, "jpeg") buf_str = buf.getvalue() base64_data = base64.b64encode(buf_str).decode() id = uuid.uuid1().__str__() session[id] = code body = self.body.format(base64_data=base64_data, error=error) response = HTTPResponse(body, content_type="text/html; charset=utf-8") response.cookies["uuid"] = id return responseapp.add_route(SimpleView.as_view(), '/code')if __name__ == "__main__": app.run(host="0.0.0.0", port=8000)
只是简单的实现了验证码,没有实现点击刷新,点击刷新的原理不难:异步请求+刷新接口就好了,记得更新对应的session的key里面的value
0人点赞
随笔