172 lines
6.0 KiB
Python
172 lines
6.0 KiB
Python
"""认证鉴权路由(A1)
|
||
|
||
POST /auth/register 用户注册
|
||
POST /auth/wework-login 企微登录
|
||
POST /auth/password-login 账密登录
|
||
POST /auth/send-email-code 发送注册邮箱验证码
|
||
POST /auth/forgot-password/send-code 发送找回密码验证码
|
||
POST /auth/reset-password 通过邮箱重置密码
|
||
POST /auth/refresh-token 刷新 Token
|
||
POST /auth/logout 退出登录
|
||
"""
|
||
from flask import Blueprint, request, jsonify
|
||
from insurance.auth.service import AuthService
|
||
from insurance.middleware.auth_middleware import jwt_required
|
||
|
||
auth_bp = Blueprint("auth", __name__)
|
||
auth_service = AuthService()
|
||
|
||
|
||
def _error_status(result: dict) -> int:
|
||
"""配置/服务端错误返回 500,用户输入错误返回 400。"""
|
||
return 500 if result.get("code") == 5001 else 400
|
||
|
||
|
||
@auth_bp.route("/register", methods=["POST"])
|
||
def register():
|
||
"""用户注册。"""
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({"code": 1001, "message": "请求体不能为空", "data": None}), 400
|
||
username = data.get("username", "")
|
||
password = data.get("password", "")
|
||
email = data.get("email", "")
|
||
real_name = data.get("real_name", "")
|
||
code = data.get("code", "")
|
||
|
||
if not username or not password or not email or not real_name or not code:
|
||
return jsonify({"code": 1001, "message": "请输入用户名、密码、邮箱、真实姓名和验证码", "data": None}), 400
|
||
|
||
result = auth_service.register(username, password, email, real_name, code)
|
||
if result["code"] != 0:
|
||
return jsonify(result), _error_status(result)
|
||
return jsonify(result)
|
||
|
||
|
||
@auth_bp.route("/send-email-code", methods=["POST"])
|
||
def send_email_code():
|
||
"""发送注册邮箱验证码。"""
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({"code": 1001, "message": "请求体不能为空", "data": None}), 400
|
||
result = auth_service.send_email_code(
|
||
data.get("email", ""),
|
||
"register",
|
||
request.remote_addr or "",
|
||
)
|
||
if result["code"] != 0:
|
||
return jsonify(result), _error_status(result)
|
||
return jsonify(result)
|
||
|
||
|
||
@auth_bp.route("/forgot-password/send-code", methods=["POST"])
|
||
def forgot_password_send_code():
|
||
"""发送找回密码邮箱验证码。"""
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({"code": 1001, "message": "请求体不能为空", "data": None}), 400
|
||
result = auth_service.send_email_code(
|
||
data.get("email", ""),
|
||
"reset_password",
|
||
request.remote_addr or "",
|
||
)
|
||
if result["code"] != 0:
|
||
return jsonify(result), _error_status(result)
|
||
return jsonify(result)
|
||
|
||
|
||
@auth_bp.route("/reset-password", methods=["POST"])
|
||
def reset_password():
|
||
"""通过邮箱验证码重置密码。"""
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({"code": 1001, "message": "请求体不能为空", "data": None}), 400
|
||
email = data.get("email", "")
|
||
code = data.get("code", "")
|
||
new_password = data.get("new_password", "")
|
||
|
||
if not email or not code or not new_password:
|
||
return jsonify({"code": 1001, "message": "请输入邮箱、验证码和新密码", "data": None}), 400
|
||
|
||
result = auth_service.reset_password(email, code, new_password)
|
||
if result["code"] != 0:
|
||
return jsonify(result), _error_status(result)
|
||
return jsonify(result)
|
||
|
||
|
||
@auth_bp.route("/wework-login", methods=["POST"])
|
||
def wework_login():
|
||
"""企微登录:接收企微授权 code,签发 JWT。"""
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({"code": 1001, "message": "请求体不能为空", "data": None}), 400
|
||
code = data.get("code", "")
|
||
state = data.get("state", "")
|
||
|
||
if not code:
|
||
return jsonify({"code": 1001, "message": "授权码无效", "data": None}), 400
|
||
|
||
result = auth_service.wework_login(code, state)
|
||
return jsonify(result)
|
||
|
||
|
||
@auth_bp.route("/password-login", methods=["POST"])
|
||
def password_login():
|
||
"""账密登录:校验用户名密码,返回 JWT。"""
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({"code": 1001, "message": "请求体不能为空", "data": None}), 400
|
||
username = data.get("username", "")
|
||
password = data.get("password", "")
|
||
|
||
if not username or not password:
|
||
return jsonify({"code": 1001, "message": "请输入用户名和密码", "data": None}), 400
|
||
|
||
result = auth_service.password_login(username, password)
|
||
if result["code"] != 0:
|
||
return jsonify(result), 401
|
||
return jsonify(result)
|
||
|
||
|
||
@auth_bp.route("/refresh-token", methods=["POST"])
|
||
@jwt_required
|
||
def refresh_token():
|
||
"""刷新过期 Token。"""
|
||
user_id = request.user_id
|
||
result = auth_service.refresh_token(user_id)
|
||
return jsonify(result)
|
||
|
||
|
||
@auth_bp.route("/logout", methods=["POST"])
|
||
@jwt_required
|
||
def logout():
|
||
"""吊销当前 Token。"""
|
||
token = request.headers.get("Authorization", "").replace("Bearer ", "")
|
||
user_id = request.user_id
|
||
result = auth_service.logout(token, user_id)
|
||
return jsonify(result)
|
||
|
||
|
||
@auth_bp.route("/change-password", methods=["POST"])
|
||
@jwt_required
|
||
def change_password():
|
||
"""修改密码。"""
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({"code": 1001, "message": "请求体不能为空", "data": None}), 400
|
||
old_password = data.get("old_password", "")
|
||
new_password = data.get("new_password", "")
|
||
|
||
if not old_password or not new_password:
|
||
return jsonify({"code": 1001, "message": "请输入旧密码和新密码", "data": None}), 400
|
||
|
||
# 密码强度校验:8-128 位,至少包含字母和数字
|
||
if len(new_password) < 8 or len(new_password) > 128:
|
||
return jsonify({"code": 1001, "message": "密码长度需在 8-128 之间", "data": None}), 400
|
||
if not any(c.isalpha() for c in new_password) or not any(c.isdigit() for c in new_password):
|
||
return jsonify({"code": 1001, "message": "密码需包含字母和数字", "data": None}), 400
|
||
|
||
user_id = request.user_id
|
||
result = auth_service.change_password(user_id, old_password, new_password)
|
||
return jsonify(result)
|