95 lines
3.7 KiB
Python
95 lines
3.7 KiB
Python
from flask import Flask, jsonify, request
|
||
from flask_cors import CORS
|
||
from flask_jwt_extended import JWTManager, get_jwt_identity, verify_jwt_in_request
|
||
from flask_jwt_extended.exceptions import JWTDecodeError, NoAuthorizationError, InvalidHeaderError
|
||
from config import Config
|
||
from models import db
|
||
from routes.auth import auth_bp
|
||
from routes.tokens import tokens_bp
|
||
from routes.dashboard import dashboard_bp
|
||
from routes.logs import logs_bp
|
||
from routes.recharge import recharge_bp
|
||
from routes.user import user_bp
|
||
from routes.models import models_bp
|
||
import logging
|
||
|
||
# 配置日志
|
||
logging.basicConfig(level=logging.INFO)
|
||
logger = logging.getLogger(__name__)
|
||
|
||
def create_app():
|
||
app = Flask(__name__)
|
||
app.config.from_object(Config)
|
||
|
||
# 请求前钩子:记录请求信息(用于调试)
|
||
@app.before_request
|
||
def log_request():
|
||
if request.path.startswith('/api/') and request.path != '/api/auth/login' and request.path != '/api/auth/register':
|
||
auth_header = request.headers.get('Authorization', 'None')
|
||
logger.info(f"[{request.method}] {request.path}")
|
||
logger.info(f"Authorization Header: {auth_header[:80] if auth_header != 'None' else 'Missing'}")
|
||
|
||
# 初始化扩展
|
||
db.init_app(app)
|
||
# CORS配置:允许所有来源,并支持credentials
|
||
CORS(app,
|
||
resources={r"/api/*": {
|
||
"origins": "*",
|
||
"methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
||
"allow_headers": ["Content-Type", "Authorization"],
|
||
"supports_credentials": True
|
||
}},
|
||
supports_credentials=True)
|
||
jwt = JWTManager(app)
|
||
|
||
# JWT错误处理器
|
||
@jwt.expired_token_loader
|
||
def expired_token_callback(jwt_header, jwt_payload):
|
||
logger.warning(f"Token expired: {jwt_payload}")
|
||
return jsonify({'error': 'Token已过期,请重新登录'}), 401
|
||
|
||
@jwt.invalid_token_loader
|
||
def invalid_token_callback(error):
|
||
auth_header = request.headers.get('Authorization', 'None')
|
||
logger.error(f"Invalid token error: {str(error)}")
|
||
logger.error(f"Authorization header: {auth_header[:100] if auth_header != 'None' else 'Missing'}")
|
||
return jsonify({
|
||
'error': '无效的Token',
|
||
'detail': str(error),
|
||
'hint': '请检查Authorization头格式是否正确(应为: Bearer <token>)'
|
||
}), 422
|
||
|
||
@jwt.unauthorized_loader
|
||
def missing_token_callback(error):
|
||
logger.warning(f"Missing token: {str(error)}")
|
||
auth_header = request.headers.get('Authorization', 'None')
|
||
logger.warning(f"Authorization header: {auth_header[:100] if auth_header != 'None' else 'Missing'}")
|
||
return jsonify({
|
||
'error': '缺少认证Token,请先登录',
|
||
'detail': str(error)
|
||
}), 401
|
||
|
||
@jwt.needs_fresh_token_loader
|
||
def token_not_fresh_callback(jwt_header, jwt_payload):
|
||
logger.warning(f"Token not fresh: {jwt_payload}")
|
||
return jsonify({'error': 'Token需要刷新'}), 401
|
||
|
||
# 注册蓝图
|
||
app.register_blueprint(auth_bp, url_prefix='/api/auth')
|
||
app.register_blueprint(tokens_bp, url_prefix='/api/tokens')
|
||
app.register_blueprint(dashboard_bp, url_prefix='/api/dashboard')
|
||
app.register_blueprint(logs_bp, url_prefix='/api/logs')
|
||
app.register_blueprint(recharge_bp, url_prefix='/api/recharge')
|
||
app.register_blueprint(user_bp, url_prefix='/api/user')
|
||
app.register_blueprint(models_bp, url_prefix='/api/models')
|
||
|
||
# 创建数据库表
|
||
with app.app_context():
|
||
db.create_all()
|
||
|
||
return app
|
||
|
||
if __name__ == '__main__':
|
||
app = create_app()
|
||
app.run(debug=True, host='0.0.0.0', port=5000)
|