Repository navigation
BUG: do not move api_key to a cookie on WebSocket connections - #99
Open
SeijDeLeon wants to merge 1 commit into
Open
SeijDeLeon wants to merge 1 commit into
SeijDeLeon wants to merge 1 commit into
Conversation
The `set_cookies` HTTP middleware initializes `request.state.cookies_to_set`, but that middleware does not run for WebSocket connections. `move_api_key()` assumed the attribute was always present, so authenticating a WebSocket with `?api_key=...` raised an AttributeError. Skip setting the cookie when there is no place to store it, and add regression tests covering both paths. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
set_cookiesHTTP middleware initializesrequest.state.cookies_to_set, but that middleware does not run for WebSocket connections.move_api_key()assumed the attribute was always present, so authenticating a WebSocket with?api_key=...raised an AttributeError. Skip setting the cookie when there is no place to store it, and add regression tests covering both paths.Description
move_api_key()unconditionally appended torequest.state.cookies_to_set.That attribute is initialized by the
set_cookiesHTTP middleware inapp.py, which is registered with@app.middleware("http")and thereforenever runs for WebSocket connections. On the WebSocket path the attribute
does not exist, so the append raised
AttributeError.move_api_key()now checks for the attribute and skips setting the cookiewhen it is absent, logging at debug level. The HTTP path is unchanged.
Motivation and Context
Opening a WebSocket with the API key in the query string — e.g.
/console_output/ws?api_key=...— fails with anAttributeError.The path is:
get_current_principal_websocket()readsapi_keyfromwebsocket.query_paramsand callsget_current_principal(), which callsmove_api_key()after resolving the principal. Becausemove_api_key()onlyacts when
"api_key" in request.query_params, the header form(
Authorization: ApiKey ...) and the first-message{"type": "auth"}handshake are unaffected — only the query-parameter form reaches the bug.
The
AttributeErroris also not contained:get_current_principal_websocket()catches
HTTPExceptiononly, so it propagates out of the socket route ratherthan surfacing as a clean auth failure.
Setting a cookie is meaningless on a WebSocket handshake in any case — there is
no response object to attach it to. Browsers that open a socket with
?api_key=...should establish the cookie via an ordinary HTTP request.Addresses #94
Summary of Changes for Release Notes
Fixed
AttributeErrorwhen authenticating a WebSocket connection with anAPI key passed as a query parameter (e.g.
/console_output/ws?api_key=...).How Has This Been Tested?
Added two regression tests to
src/bluesky_httpserver/tests/test_auth_for_websockets.py, drivingmove_api_key()with a realstarlette.datastructures.State:test_move_api_key_sets_cookie_on_http_request— withcookies_to_setinitialized, the cookie is still queued (guards against regressing the HTTP
path).
test_move_api_key_skips_cookie_on_websocket_request— with the attributeabsent, the call returns without raising and sets nothing.
Also tested this by hand in a web browser with Finch and using Postman.