You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

55 lines
1.9 KiB

from PIL import Image, ImageDraw, ImageFont,ImageFilter
import random
import string
import io
from functools import wraps
from quart import session, redirect, url_for, flash,current_app
def generate_captcha():
characters = string.ascii_uppercase + string.digits
captcha_text = ''.join(random.choices(characters, k=6))
font = ImageFont.truetype("arial.ttf", 36)
image = Image.new('RGB', (200, 60), color=(255, 255, 255))
draw = ImageDraw.Draw(image)
for i in range(6):
draw.text((10 + i * 30, 10), captcha_text[i], font=font,
fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
# 模糊化处理
image = image.filter(ImageFilter.BLUR)
# 将图片保存到BytesIO流中
buffer = io.BytesIO()
image.save(buffer, 'jpeg')
buffer.seek(0)
# captcha_path = os.path.join('static', 'captcha', f'{captcha_text}.png')
# image.save(captcha_path)
# return captcha_text, f'static/captcha/{captcha_text}.png'
return captcha_text, buffer
def verify_captcha(user_input, actual_captcha):
return user_input == actual_captcha
def login_required(f):
@wraps(f)
async def decorated_function(*args, **kwargs):
username = session.get('user')
token = session.get('token')
if not username or not token:
await flash('未登录,请重新登录', 'error')
return redirect(url_for('main.login'))
#从redis取最新的token
redis_key = f"user_token:{username}"
server_token = await current_app.redis.get(redis_key)
if server_token is None or server_token != token:
# 如果不匹配,说明此账号已在其他地方登录
session.clear()
await flash('您的账号已在其他设备登录,请重新登录', 'error')
return redirect(url_for('main.login'))
return await f(*args, **kwargs)
return decorated_function