5eecbecd7f
- Portal: wrap .panel-head in matching card (border, radius, shadow) with cyan->purple left accent bar; h2 28px -> 20px; description right-aligned with vertical divider; top edge now aligns with side-menu & links-panel - Login: switch from absolute-positioned icons to el-input prefix slot; layout brand row (logo + title + uppercase subtitle); add form-title section with gradient bar; consistent cyan focus; gradient button; dashed top divider for back-link; card width 420 -> 460 - Add .gitignore (node_modules, dist, __pycache__, .env, etc.)
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
"""Auth API."""
|
|
from flask import Blueprint, jsonify, request
|
|
|
|
from auth import get_current_user, issue_token
|
|
from models import User
|
|
|
|
bp = Blueprint("auth", __name__, url_prefix="/api/auth")
|
|
|
|
|
|
@bp.route("/login", methods=["POST"])
|
|
def login():
|
|
data = request.get_json(silent=True) or {}
|
|
username = (data.get("username") or "").strip()
|
|
password = data.get("password") or ""
|
|
user = User.query.filter_by(username=username).first()
|
|
if not user or not user.check_password(password):
|
|
return jsonify({"error": "用户名或密码错误"}), 401
|
|
return jsonify({"token": issue_token(user), "username": user.username})
|
|
|
|
|
|
@bp.route("/me")
|
|
def me():
|
|
user = get_current_user()
|
|
if not user:
|
|
return jsonify({"error": "未登录"}), 401
|
|
return jsonify({"username": user.username})
|
|
|
|
|
|
@bp.route("/password", methods=["POST"])
|
|
def change_password():
|
|
user = get_current_user()
|
|
if not user:
|
|
return jsonify({"error": "未登录"}), 401
|
|
data = request.get_json(silent=True) or {}
|
|
old = data.get("old_password") or ""
|
|
new = data.get("new_password") or ""
|
|
if not user.check_password(old):
|
|
return jsonify({"error": "原密码错误"}), 400
|
|
if len(new) < 6:
|
|
return jsonify({"error": "新密码至少 6 位"}), 400
|
|
from extensions import db
|
|
user.set_password(new)
|
|
db.session.commit()
|
|
return jsonify({"message": "密码已修改"})
|