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