web驗證碼的簡單實現


最近有小夥伴提問:能否說下web驗證的原理,感覺文字描述不清楚,於是就用代碼簡單的演示下:此代碼是需要依賴:

<code>sanic==19.9.0Pillow==7.0.0
/<code>
web驗證碼的簡單實現

<code>import random
import string
import uuid
import base64
import platform
from PIL import Image, ImageDraw,ImageFont
from io import BytesIO
from sanic import Sanic
from sanic.response import HTTPResponse,text
from sanic.views import HTTPMethodView


app = 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:\\WINDOWS\\Fonts\\STXINGKA.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, code


class SimpleView(HTTPMethodView):
body = """



<title>登錄/<title>
<link>

<link>







"""

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 response


app.add_route(SimpleView.as_view(), '/code')

if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
/<code>

只是簡單的實現了驗證碼,沒有實現點擊刷新,點擊刷新的原理不難:異步請求+刷新接口就好了,記得更新對應的session的key裡面的value

隨筆


分享到:


相關文章: