JupyterHub / JupyterServerProxy 403 to OPTIONS request (CORS preflight)

I’m utilizing a JupyterHub setup with Docker, where JupyterHub operates in its container, and the docker spawner spawns user containers. Additionally, there’s a separate container running configurable-http-proxy. Within the user containers, the jupyter-server-proxy extension is installed.

When a user launches a custom FastAPI/Uvicorn server in a notebook, accessing it via /user//proxy//… is seamless as long as the user is authenticated. I’ve also successfully accessed the URL using a Python script with authorization via a generated token.

However, one of my users needs to access this URL from a web app, which introduces a cross-site request challenge. The preflight/OPTIONS request results in a 403 Forbidden error, followed by a CORS error due to the missing access-control-allow-origin header.

Setting mode=no-cors for the JavaScript fetch eliminates the need for the OPTIONS request. However, this prevents the attachment of the authorization header (including the token) with the request, redirecting to the login page upon access.

I suspect the OPTIONS requests are being blocked before reaching the FastAPI/Uvicorn server via jupyter-server-proxy, as authentication hasn’t occurred at that stage and the options request does not contain the authorization header.

It would be sufficient to allow specific origins/methods/headers universally for all users.

How can I deal with the OPTIONS request so they do not get blocked but instead return a response with the allowed origins/methods/headers? Is such a setup even possible?
Any insights or suggestions would be greatly appreciated!

There’s potentially three components to consider.

jupyter-server-proxy: it’s a jupyter-server extension which mostly passes requests through so any CORS checks should be in jupyter-server, however it might be worth adding some debug logging in your proxied application to check what headers are being received

Your application that you’re proxying: is it also doing it’s own CORS checks?

Thanks for your answer.

Right now I do no longer need a solution for this problem.Our student managed to find an alternate solution, she used websockets instead and the communication between her webapp and the server finally worked.

I will test the c.ServerApp.allow_origin option and see if that would work - although I’m pretty sure I already tried that.

jupyter-server-proxy: It seems like the OPTIONS request is not passed through. Debug logging is a good idea - maybe it adds some insight.

The application that gets proxied was at that point a very simple FastAPI/Uvicorn setup (when url with /images is accessed it sent a json file) with minimal config (config = uvicorn.Config(app, host="", port=8810, log_level="info")). I tried adding the CORS related headers there - but the requests from the webapp never reached this proxied server. When the requests came from a python script (no cors needed) I could see that adding the headers worked. I have never seen the webapp code - just the running webpage of the app.