Skip to content

Commit 217de9c

Browse files
author
happy-devs
committed
CORS updates
- Set allow_origins to ["*"] for production mode - Disable credentials when using wildcard origins (CORS requirement) - Update CORSHandlerMiddleware to handle all origins properly - Maintain localhost support with credentials for local development 🤖 Generated with [Claude Code](https://claude.ai/code)
1 parent 066834c commit 217de9c

3 files changed

Lines changed: 30 additions & 24 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,4 @@ Taskfile.yml
149149
/logs
150150
webapp_logs.zip
151151
/.schemas
152+
app_logs.zip

main.py

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,23 +102,39 @@ async def global_exception_handler(request: Request, exc: Exception):
102102
"http://127.0.0.1:3000"
103103
]
104104

105+
# Production origins for different environments
106+
production_origins = [
107+
"https://signals.data.undp.org",
108+
"https://thankful-forest-05a90a303-staging.westeurope.3.azurestaticapps.net",
109+
"https://signals-staging.data.undp.org"
110+
]
111+
105112
# Create a custom middleware class for handling CORS
106113
class CORSHandlerMiddleware(BaseHTTPMiddleware):
107114
async def dispatch(self, request: Request, call_next):
108115
# Handle OPTIONS preflight requests
109116
if request.method == "OPTIONS":
110-
headers = {
111-
"Access-Control-Allow-Origin": "*",
112-
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS, PATCH",
113-
"Access-Control-Allow-Headers": "access_token, Authorization, Content-Type, Accept, X-API-Key",
114-
"Access-Control-Allow-Credentials": "true",
115-
"Access-Control-Max-Age": "600", # Cache preflight for 10 minutes
116-
}
117-
118-
# Set specific origin if in local mode
119117
origin = request.headers.get("origin")
120-
if os.environ.get("ENV_MODE") == "local" and origin:
121-
headers["Access-Control-Allow-Origin"] = origin
118+
119+
# Allow all origins but handle credentials properly
120+
if os.environ.get("ENV_MODE") == "local" and origin in local_origins:
121+
# Local mode: allow specific origins with credentials
122+
headers = {
123+
"Access-Control-Allow-Origin": origin,
124+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS, PATCH",
125+
"Access-Control-Allow-Headers": "access_token, Authorization, Content-Type, Accept, X-API-Key",
126+
"Access-Control-Allow-Credentials": "true",
127+
"Access-Control-Max-Age": "600",
128+
}
129+
else:
130+
# Production mode: allow all origins without credentials
131+
headers = {
132+
"Access-Control-Allow-Origin": "*",
133+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS, PATCH",
134+
"Access-Control-Allow-Headers": "access_token, Authorization, Content-Type, Accept, X-API-Key",
135+
"Access-Control-Allow-Credentials": "false",
136+
"Access-Control-Max-Age": "600",
137+
}
122138

123139
return JSONResponse(content={}, status_code=200, headers=headers)
124140

@@ -141,11 +157,11 @@ async def dispatch(self, request: Request, call_next):
141157
expose_headers=["*"],
142158
)
143159
else:
144-
# Production mode - use more restrictive CORS
160+
# Production mode - allow all origins for client flexibility
145161
app.add_middleware(
146162
CORSMiddleware,
147163
allow_origins=["*"],
148-
allow_credentials=True,
164+
allow_credentials=False, # Must be False when allow_origins is ["*"]
149165
allow_methods=["*"],
150166
allow_headers=["*", "access_token", "Authorization", "Content-Type"],
151167
)

src/main.py

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)