目录

一、获取“发件箱”通行证

1、进入QQ邮箱

2、绑定手机号

3、设置独立密码和文件夹区域锁(可选)

4、开启POP3/IMAP/SMTP/Exchange/CardDAV 服务

二、执行示例

2.1 安装依赖

2.2 配置文件:.env

2.3 服务端:main.py

2.4 前端(注册登录):index.html

三、执行流程

四、扩展方案



前言

只需要一个个人邮箱,即可为你的应用构建完整的用户注册登录体系。

适用人群

163邮箱验证的“POP3/SMTP/IMAP”服务,对独立开发友好,实现简单又给登录注册提供了安全性;


适用场景
适合开发环境、早期和小型生产环境,但在用户量增大或对可靠性要求极高时,需要升级方案。


一、获取“发件箱”通行证

1、进入QQ邮箱

官网地址:https://wx.mail.qq.com/

2、绑定手机号

3、设置独立密码和文件夹区域锁(可选)

功能 保护范围 相当于
独立密码 整个邮箱入口 邮箱的“第二把锁”
文件夹区域加锁 邮箱内的特定区域(文件夹/记事本等) 邮箱内的“保险柜”

独立密码

  • 作用:设置后,在登录QQ邮箱时必须额外输入这个密码才能进入(即使你已经登录了QQ或微信)。

  • 使用场景:如果你在公共场所或他人设备上登录QQ,担心他人直接访问你的邮箱,可以启用独立密码,相当于多一层身份验证。

  • 简单说:像是给你的邮箱“加一道门”,即使QQ已登录,没这个密码也进不去邮箱。


文件夹区域加锁

  • 作用:对“我的文件夹”“代收邮箱”“记事本”这三个区域单独设置密码保护。

  • 使用场景:即使别人能进入你的邮箱(比如知道独立密码或通过你已登录的电脑),也无法直接查看你这些加密区域的内容,必须再次输入区域密码。

  • 简单说:像是邮箱里的“保险柜”,把重要文件夹再锁一层。

4、开启POP3/IMAP/SMTP/Exchange/CardDAV 服务

开启后会有一个16位的授权码,记得保存好只出现一次

到这邮箱验证码的验证登录服务就开通好了


二、执行示例

以下是通过其他qq邮箱注册登录示例


2.1 安装依赖

pip install python-dotenv
pip install fastapi uvicorn python-multipart

2.2 配置文件:.env

# QQ邮箱配置
# SMTP 配置
SMTP_HOST = smtp.qq.com
SMTP_PORT = 465
SMTP_USER = *****@qq.com       #替换为你的qq邮箱
SMTP_PASS = ******tjncgid      #替换为你的授权码

2.3 服务端:main.py

#启动命令:uvicorn main:app --reload
#默认地址:http://127.0.0.1:8000

import random
import smtplib
from email.mime.text import MIMEText
from datetime import datetime, timedelta

from fastapi import FastAPI, Form
from fastapi.middleware.cors import CORSMiddleware
from dotenv import load_dotenv
import os
# ====== 1️⃣ 加载 .env ======
load_dotenv()

app = FastAPI()

# 允许前端直接访问(测试用)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
)

# ====== 配置你的 QQ 邮箱 ======
SMTP_HOST = os.getenv("SMTP_HOST")
SMTP_PORT = int(os.getenv("SMTP_PORT"))
SMTP_USER = os.getenv("SMTP_USER")
SMTP_PASS = os.getenv("SMTP_PASS")

# ====== 内存存储(测试用) ======
code_store = {}      # email -> {code, expire}
user_store = set()   # 模拟用户表


def send_email(to_email: str, code: str):
    msg = MIMEText(f"你的验证码是:{code},5 分钟内有效", "plain", "utf-8")
    msg["Subject"] = "登录验证码"
    msg["From"] = SMTP_USER
    msg["To"] = to_email

    with smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT) as server:
        server.login(SMTP_USER, SMTP_PASS)
        server.send_message(msg)


@app.post("/send-code")
def send_code(email: str = Form(...)):
    code = str(random.randint(100000, 999999))
    expire = datetime.now() + timedelta(minutes=5)

    code_store[email] = {
        "code": code,
        "expire": expire
    }

    send_email(email, code)
    return {"msg": "验证码已发送"}


@app.post("/login")
def login(email: str = Form(...), code: str = Form(...)):
    record = code_store.get(email)
    if not record:
        return {"msg": "请先获取验证码"}

    if datetime.now() > record["expire"]:
        return {"msg": "验证码已过期"}

    if record["code"] != code:
        return {"msg": "验证码错误"}

    # 登录 / 注册合一
    if email not in user_store:
        user_store.add(email)
        msg = "注册成功并登录"
    else:
        msg = "登录成功"

    # 用完即删
    del code_store[email]

    return {
        "status": "ok",
        "msg": msg
    }

2.4 前端(注册登录):index.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>邮箱验证码登录</title>
</head>
<body>
<h2>邮箱验证码注册 / 登录</h2>

<input id="email" placeholder="请输入邮箱"><br><br>
<button onclick="sendCode()">发送验证码</button><br><br>

<input id="code" placeholder="请输入验证码"><br><br>
<button onclick="login()">登录 / 注册</button>

<pre id="result"></pre>

<script>
const API = "http://127.0.0.1:8000";

function sendCode() {
    const email = document.getElementById("email").value;
    fetch(API + "/send-code", {
        method: "POST",
        body: new URLSearchParams({email})
    })
    .then(res => res.json())
    .then(data => result.innerText = JSON.stringify(data, null, 2));
}

function login() {
    const email = document.getElementById("email").value;
    const code = document.getElementById("code").value;
    fetch(API + "/login", {
        method: "POST",
        body: new URLSearchParams({email, code})
    })
    .then(res => res.json())
    .then(data => result.innerText = JSON.stringify(data, null, 2));
}
</script>
</body>
</html>

三、执行流程

1、启动服务端main.py,执行以下命令:

uvicorn main:app --reload

2、双击打开index.html:


四、扩展方案

1、说明

现在这套是一个完整闭环示例

.env 配置
✔ SMTP 发信
✔ 验证码校验
✔ 注册 / 登录合一
✔ 前端阻断异常

👉 已经是一个可上线原型

2、优化方向

  • 🔐 JWT 登录态(前端存 token)

  • 📦 Redis 验证码(多实例可用)

  • 🧱 Vue3 版本(组件化)

  • 🛡️ 防刷 / 限流 / IP 控制

  • 📧 备用 SMTP(QQ + 163)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐