Files

62 lines
1.8 KiB
Python
Raw Permalink Normal View History

"""认证:密码哈希、令牌签发/校验、短信验证码(兼容原 mock 方案)"""
import base64
import hashlib
import json
import time
import random
import re
SECRET = "pine-mock-secret-2026"
TOKEN_TTL_MS = 1000 * 60 * 60 * 12 # 12h
PHONE_RE = re.compile(r"^1\d{10}$")
CODE_TTL = 5 * 60 # 5 min
# 演示环境:内存验证码 mapphone -> {code, exp}),响应返回 debugCode
sms_codes: dict[str, dict] = {}
def hash_password(s: str) -> str:
return hashlib.sha256(str(s).encode()).hexdigest()
def b64url(data: bytes) -> str:
return base64.urlsafe_b64encode(data).rstrip(b"=").decode()
def make_token(username: str) -> str:
payload = b64url(json.dumps({"username": username, "exp": int(time.time() * 1000) + TOKEN_TTL_MS}).encode())
sig = b64url((SECRET + "." + payload).encode())
return f"{payload}.{sig}"
def verify_token(token: str):
if not token or not isinstance(token, str):
return None
parts = token.split(".")
if len(parts) != 2:
return None
payload_part, sig_part = parts
if b64url((SECRET + "." + payload_part).encode()) != sig_part:
return None
try:
payload = json.loads(base64.urlsafe_b64decode(payload_part + "=" * (-len(payload_part) % 4)).decode())
if not payload.get("exp") or payload["exp"] < time.time() * 1000:
return None
return {"username": payload["username"]}
except Exception:
return None
def send_sms_code(phone: str) -> str:
code = str(random.randint(100000, 999999))
sms_codes[phone] = {"code": code, "exp": time.time() + CODE_TTL}
return code
def check_sms_code(phone: str, code: str) -> bool:
rec = sms_codes.get(phone)
if not rec or rec["code"] != str(code) or time.time() > rec["exp"]:
return False
sms_codes.pop(phone, None)
return True