""" 认证蓝图:登录页(仅 GET 渲染模板)+ 登出(清 JWT cookie)+ token 同步 登录表单提交已经直连 Java 后端 /login,Python 这边只负责: 1. 渲染登录页模板 2. 把 Java 签发的 JWT 从前端写到 Python 同源 cookie,供后续页面跳转携带 3. 登出:清 cookie 跳回登录页 """ import sys from flask import Blueprint, redirect, url_for, make_response, request, jsonify from app_common import _render_html, current_user_id from config import JAVA_API_BASE from jwt_util import COOKIE_NAME, parse_token_with_reason auth_bp = Blueprint('auth', __name__) @auth_bp.route('/login', methods=['GET']) def login(): if current_user_id(): return redirect(url_for('main.home')) return _render_html('login.html', java_api_base=JAVA_API_BASE) @auth_bp.route('/api/auth/sync', methods=['POST']) def api_auth_sync(): """前端拿到 Java 返回的 JWT 后调用,把 token 写进 Python 同源 cookie。""" data = request.get_json(silent=True) or {} token = (data.get('token') or '').strip() if not token: return jsonify({'success': False, 'error': '缺少 token'}), 400 payload, reason = parse_token_with_reason(token) if not payload: # 把根因打到服务端日志,并回传给前端,便于现场排查 print(f"[auth] /api/auth/sync 校验失败: {reason}", file=sys.stderr) return jsonify({'success': False, 'error': f'token 无效: {reason}'}), 401 resp = make_response(jsonify({'success': True})) resp.set_cookie( COOKIE_NAME, token, max_age=7 * 24 * 3600, path='/', httponly=True, samesite='Lax', ) return resp @auth_bp.route('/logout') def logout(): resp = make_response(redirect(url_for('auth.login'))) resp.delete_cookie(COOKIE_NAME, path='/') return resp