mirror of
https://github.com/langgenius/dify.git
synced 2026-05-12 15:58:19 +08:00
120 lines
4.6 KiB
Python
120 lines
4.6 KiB
Python
from configs import dify_config
|
|
from constants import HEADER_NAME_APP_CODE, HEADER_NAME_CSRF_TOKEN, HEADER_NAME_PASSPORT
|
|
from dify_app import DifyApp
|
|
|
|
BASE_CORS_HEADERS: tuple[str, ...] = ("Content-Type", HEADER_NAME_APP_CODE, HEADER_NAME_PASSPORT)
|
|
SERVICE_API_HEADERS: tuple[str, ...] = (*BASE_CORS_HEADERS, "Authorization")
|
|
AUTHENTICATED_HEADERS: tuple[str, ...] = (*SERVICE_API_HEADERS, HEADER_NAME_CSRF_TOKEN)
|
|
FILES_HEADERS: tuple[str, ...] = (*BASE_CORS_HEADERS, HEADER_NAME_CSRF_TOKEN)
|
|
EMBED_HEADERS: tuple[str, ...] = ("Content-Type", HEADER_NAME_APP_CODE)
|
|
EXPOSED_HEADERS: tuple[str, ...] = ("X-Version", "X-Env", "X-Trace-Id")
|
|
OPENAPI_HEADERS: tuple[str, ...] = ("Authorization", "Content-Type", HEADER_NAME_CSRF_TOKEN)
|
|
OPENAPI_MAX_AGE_SECONDS: int = 600
|
|
|
|
|
|
def _apply_cors_once(bp, /, **cors_kwargs):
|
|
"""Make CORS idempotent so blueprints can be reused across multiple app instances."""
|
|
|
|
if getattr(bp, "_dify_cors_applied", False):
|
|
return
|
|
|
|
from flask_cors import CORS
|
|
|
|
CORS(bp, **cors_kwargs)
|
|
bp._dify_cors_applied = True
|
|
|
|
|
|
def init_app(app: DifyApp):
|
|
# register blueprint routers
|
|
|
|
from controllers.console import bp as console_app_bp
|
|
from controllers.files import bp as files_bp
|
|
from controllers.inner_api import bp as inner_api_bp
|
|
from controllers.mcp import bp as mcp_bp
|
|
from controllers.openapi import bp as openapi_bp
|
|
from controllers.service_api import bp as service_api_bp
|
|
from controllers.trigger import bp as trigger_bp
|
|
from controllers.web import bp as web_bp
|
|
|
|
_apply_cors_once(
|
|
service_api_bp,
|
|
allow_headers=list(SERVICE_API_HEADERS),
|
|
methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"],
|
|
expose_headers=list(EXPOSED_HEADERS),
|
|
)
|
|
app.register_blueprint(service_api_bp)
|
|
|
|
# User-scoped programmatic API. Default empty allowlist = same-origin
|
|
# only; expand via OPENAPI_CORS_ALLOW_ORIGINS for third-party
|
|
# integrations. supports_credentials so cookie-authed approve/deny
|
|
# work; cross-origin OPTIONS without an allowed origin will fail
|
|
# the same as on the console blueprint.
|
|
_apply_cors_once(
|
|
openapi_bp,
|
|
resources={r"/*": {"origins": dify_config.OPENAPI_CORS_ALLOW_ORIGINS}},
|
|
supports_credentials=True,
|
|
allow_headers=list(OPENAPI_HEADERS),
|
|
methods=["GET", "POST", "PATCH", "DELETE", "OPTIONS"],
|
|
expose_headers=list(EXPOSED_HEADERS),
|
|
max_age=OPENAPI_MAX_AGE_SECONDS,
|
|
)
|
|
app.register_blueprint(openapi_bp)
|
|
|
|
_apply_cors_once(
|
|
web_bp,
|
|
resources={
|
|
# Embedded bot endpoints (unauthenticated, cross-origin safe)
|
|
r"^/chat-messages$": {
|
|
"origins": dify_config.WEB_API_CORS_ALLOW_ORIGINS,
|
|
"supports_credentials": False,
|
|
"allow_headers": list(EMBED_HEADERS),
|
|
"methods": ["GET", "POST", "OPTIONS"],
|
|
},
|
|
r"^/chat-messages/.*": {
|
|
"origins": dify_config.WEB_API_CORS_ALLOW_ORIGINS,
|
|
"supports_credentials": False,
|
|
"allow_headers": list(EMBED_HEADERS),
|
|
"methods": ["GET", "POST", "OPTIONS"],
|
|
},
|
|
# Default web application endpoints (authenticated)
|
|
r"/*": {
|
|
"origins": dify_config.WEB_API_CORS_ALLOW_ORIGINS,
|
|
"supports_credentials": True,
|
|
"allow_headers": list(AUTHENTICATED_HEADERS),
|
|
"methods": ["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"],
|
|
},
|
|
},
|
|
expose_headers=list(EXPOSED_HEADERS),
|
|
)
|
|
app.register_blueprint(web_bp)
|
|
|
|
_apply_cors_once(
|
|
console_app_bp,
|
|
resources={r"/*": {"origins": dify_config.CONSOLE_CORS_ALLOW_ORIGINS}},
|
|
supports_credentials=True,
|
|
allow_headers=list(AUTHENTICATED_HEADERS),
|
|
methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"],
|
|
expose_headers=list(EXPOSED_HEADERS),
|
|
)
|
|
app.register_blueprint(console_app_bp)
|
|
|
|
_apply_cors_once(
|
|
files_bp,
|
|
allow_headers=list(FILES_HEADERS),
|
|
methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"],
|
|
expose_headers=list(EXPOSED_HEADERS),
|
|
)
|
|
app.register_blueprint(files_bp)
|
|
|
|
app.register_blueprint(inner_api_bp)
|
|
app.register_blueprint(mcp_bp)
|
|
|
|
# Register trigger blueprint with CORS for webhook calls
|
|
_apply_cors_once(
|
|
trigger_bp,
|
|
allow_headers=["Content-Type", "Authorization", "X-App-Code"],
|
|
methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH", "HEAD"],
|
|
expose_headers=list(EXPOSED_HEADERS),
|
|
)
|
|
app.register_blueprint(trigger_bp)
|