mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-22 08:38:11 +08:00
Fixes from frontend/backend url separation (#1829)
* Fixes from frontend/backend url separation This fixes the CORS and CSP headers. Also, in thie commit, I removed the cors_supports_credentials config parameter, which was recently introduced. Instead, the logic determines the need to use CORS headers if the web_page_url is set. #1778
This commit is contained in:
@@ -341,9 +341,6 @@ def handle_api_base_url(app, app_config):
|
||||
if not api_base_url:
|
||||
return
|
||||
|
||||
if api_base_url.endswith("/"):
|
||||
api_base_url = api_base_url[:-1]
|
||||
|
||||
sha256 = hashlib.sha256(api_base_url.encode()).hexdigest()
|
||||
script_name = f"api_base_url-{sha256}.js"
|
||||
script_path = os.path.join(app.root_path, "../common/web/templates", script_name)
|
||||
|
||||
@@ -296,7 +296,7 @@ class CliLaunchServer(Server):
|
||||
"application/octet-stream",
|
||||
]
|
||||
Compress(app)
|
||||
if app_config.server_config.app__cors_supports_credentials or app_config.server_config.app__debug:
|
||||
if app_config.server_config.app__debug:
|
||||
CORS(app, supports_credentials=True)
|
||||
|
||||
|
||||
|
||||
@@ -435,7 +435,6 @@ class ServerConfig(BaseConfig):
|
||||
self.app__generate_cache_control_headers = dc["app"]["generate_cache_control_headers"]
|
||||
self.app__server_timing_headers = dc["app"]["server_timing_headers"]
|
||||
self.app__csp_directives = dc["app"]["csp_directives"]
|
||||
self.app__cors_supports_credentials = dc["app"]["cors_supports_credentials"]
|
||||
self.app__api_base_url = dc["app"]["api_base_url"]
|
||||
self.app__web_base_url = dc["app"]["web_base_url"]
|
||||
|
||||
@@ -506,7 +505,6 @@ class ServerConfig(BaseConfig):
|
||||
self.check_attr("app__flask_secret_key", (type(None), str))
|
||||
self.check_attr("app__generate_cache_control_headers", bool)
|
||||
self.check_attr("app__server_timing_headers", bool)
|
||||
self.check_attr("app__cors_supports_credentials", bool)
|
||||
self.check_attr("app__csp_directives", (type(None), dict))
|
||||
self.check_attr("app__api_base_url", (type(None), str))
|
||||
self.check_attr("app__web_base_url", (type(None), str))
|
||||
@@ -758,6 +756,8 @@ class ServerConfig(BaseConfig):
|
||||
def get_api_base_url(self):
|
||||
if self.app__api_base_url == "local":
|
||||
return f"http://{self.app__host}:{self.app__port}"
|
||||
if self.app__api_base_url and self.app__api_base_url.endswith("/"):
|
||||
return self.app__api_base_url[:-1]
|
||||
return self.app__api_base_url
|
||||
|
||||
def get_web_base_url(self):
|
||||
@@ -765,7 +765,9 @@ class ServerConfig(BaseConfig):
|
||||
return f"http://{self.app__host}:{self.app__port}"
|
||||
if self.app__web_base_url is None:
|
||||
return self.get_api_base_url()
|
||||
return self.app__web_base_url
|
||||
if self.app__web_base_url.endswith("/"):
|
||||
return self.app__web_base_url[:-1]
|
||||
return self.api__web_base_url
|
||||
|
||||
|
||||
class DatasetConfig(BaseConfig):
|
||||
|
||||
@@ -14,11 +14,6 @@ server:
|
||||
server_timing_headers: false
|
||||
csp_directives: null
|
||||
|
||||
# CORS: Cross Origin Resource Sharing. If true, this allow users to make
|
||||
# authenticated requests. This allows cookies and credentials to be submitted
|
||||
# across domains
|
||||
cors_supports_credentials: false
|
||||
|
||||
# By default, cellxgene will serve api requests from the same base url as the webpage.
|
||||
# In general api_base_url and web_base_url will not need to be set.
|
||||
# There are two reasons to set these parameters:
|
||||
|
||||
+18
-2
@@ -4,10 +4,11 @@ import sys
|
||||
import os
|
||||
import hashlib
|
||||
import base64
|
||||
from urllib.parse import urlparse
|
||||
from flask import json
|
||||
import logging
|
||||
from flask_talisman import Talisman
|
||||
|
||||
from flask_cors import CORS
|
||||
from server.common.aws_secret_utils import handle_config_from_secret
|
||||
from server.common.errors import SecretKeyRetrievalError
|
||||
|
||||
@@ -41,6 +42,14 @@ class WSGIServer(Server):
|
||||
def _before_adding_routes(app, app_config):
|
||||
script_hashes = WSGIServer.get_csp_hashes(app, app_config)
|
||||
server_config = app_config.server_config
|
||||
|
||||
# add the api_base_url to the connect_src csp header.
|
||||
extra_connect_src = []
|
||||
api_base_url = server_config.get_api_base_url()
|
||||
if api_base_url:
|
||||
parse_api_base_url = urlparse(api_base_url)
|
||||
extra_connect_src = [f"{parse_api_base_url.scheme}://{parse_api_base_url.netloc}"]
|
||||
|
||||
# This hash should be in sync with the script within
|
||||
# `client/configuration/webpack/obsoleteHTMLTemplate.html`
|
||||
|
||||
@@ -51,7 +60,7 @@ class WSGIServer(Server):
|
||||
obsolete_browser_script_hash = ["'sha256-/rmgOi/skq9MpiZxPv6lPb1PNSN+Uf4NaUHO/IjyfwM='"]
|
||||
csp = {
|
||||
"default-src": ["'self'"],
|
||||
"connect-src": ["'self'"],
|
||||
"connect-src": ["'self'"] + extra_connect_src,
|
||||
"script-src": ["'self'", "'unsafe-eval'"]
|
||||
+ obsolete_browser_script_hash + script_hashes,
|
||||
"style-src": ["'self'", "'unsafe-inline'"],
|
||||
@@ -70,6 +79,13 @@ class WSGIServer(Server):
|
||||
v = [v]
|
||||
csp[k] = csp.get(k, []) + v
|
||||
|
||||
# Add the web_base_url to the CORS header
|
||||
web_base_url = server_config.get_web_base_url()
|
||||
if web_base_url:
|
||||
web_base_url_parse = urlparse(web_base_url)
|
||||
allowed_origin = f"{web_base_url_parse.scheme}://{web_base_url_parse.netloc}"
|
||||
CORS(app, supports_credentials=True, origins=allowed_origin)
|
||||
|
||||
Talisman(
|
||||
app, force_https=server_config.app__force_https, frame_options="DENY", content_security_policy=csp,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user