BookSystem/backend/auth/utils/email.py
jayhgq 49f7022c1b feat: 添加公开注册接口,修复邮箱验证链接路径
- 新增 POST /users/register 公开注册接口(无需验证码,直接创建用户)
- 修复邮箱验证邮件中的链接路径(/verify-email → /users/verify-email)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 06:06:51 +00:00

72 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from fastapi import HTTPException
from config import email_settings
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
def _build_verification_email(token: str) -> str:
"""构建验证邮件HTML内容"""
verify_url = f"{email_settings.base_url.rstrip('/')}/users/verify-email?token={token}"
return f"""<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body style="font-family: Arial, sans-serif; padding: 20px;">
<h2>📧 邮箱验证</h2>
<p>感谢注册!请点击下方按钮完成邮箱验证:</p>
<p>
<a href="{verify_url}" style="display:inline-block;padding:12px 24px;background:#409eff;
color:#fff;text-decoration:none;border-radius:4px;font-size:16px;">
点击验证邮箱
</a>
</p>
<p>或者复制以下链接到浏览器打开:</p>
<p style="color:#909399;font-size:13px;">{verify_url}</p>
<p style="color:#909399;font-size:13px;">链接有效期为30分钟请尽快完成验证。</p>
</body>
</html>"""
async def send_verification_email(to_email: str, token: str) -> bool:
"""发送邮箱验证链接"""
try:
import aiosmtplib
msg = MIMEMultipart("alternative")
msg["Subject"] = "邮箱验证 - 图书管理系统"
msg["From"] = email_settings.from_addr
msg["To"] = to_email
msg.attach(MIMEText(_build_verification_email(token), "html", "utf-8"))
await aiosmtplib.send(
msg,
hostname=email_settings.smtp_host,
port=email_settings.smtp_port,
username=email_settings.smtp_user,
password=email_settings.smtp_password,
use_tls=email_settings.use_tls,
)
return True
except ImportError:
# aiosmtplib 未安装时降级使用标准库 smtplib
import smtplib
msg = MIMEMultipart("alternative")
msg["Subject"] = "邮箱验证 - 图书管理系统"
msg["From"] = email_settings.from_addr
msg["To"] = to_email
msg.attach(MIMEText(_build_verification_email(token), "html", "utf-8"))
if email_settings.use_tls:
server = smtplib.SMTP_SSL(email_settings.smtp_host, email_settings.smtp_port)
else:
server = smtplib.SMTP(email_settings.smtp_host, email_settings.smtp_port)
server.login(email_settings.smtp_user, email_settings.smtp_password)
server.sendmail(email_settings.from_addr, to_email, msg.as_string())
server.quit()
return True
except Exception as e:
raise HTTPException(
status_code=500,
detail="邮件发送失败,请稍后重试",
)