57 lines
1.8 KiB
Python
57 lines
1.8 KiB
Python
"""
|
||
认证蓝图:登录页(仅 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
|
||
|