Skip to content

[BUG] WebSocket callbacks do not expose request cookies/headers on callback_context #3814

Description

@i-murray

Describe your context

dash 4.2.0
dash-enterprise-auth (current)
  • Backend: FastAPI (Dash(name, backend="fastapi")); the same issue exists for the Quart backend.

Describe the bug

When a callback runs over the WebSocket transport (declared with websocket=True, or via websocket_callbacks=True), the request cookies and headers are not available on dash.callback_context. They are empty.

The HTTP transport populates these correctly (via Dash._initialize_context), but the WebSocket context builder (create_ws_context in dash/backends/ws.py) never sets cookies, headers, args, path, remote, or origin.

This breaks any authentication helper that reads the request context. In our case, running our apps on Dash Enterprise, dash_enterprise_auth.get_user_data() reads the kcIdToken cookie (or the Plotly-User-Data header on older Dash Enterprise) from callback_context.cookies. Over WebSocket it receives {}.

Steps to reproduce

fromdashimportDash, html, dcc, Input, Output, ctxapp=Dash(__name__, backend="fastapi")
app.layout=html.Div([
dcc.Input(id="q", type="text"),
html.Div(id="out"),
])
@app.callback(Output("out", "children"), Input("q", "value"), websocket=True)defshow_cookies(value):
# Over HTTP this is populated; over WebSocket it is empty.returnf"cookies={dict(ctx.cookies)} headers={bool(ctx.headers)}"if__name__=="__main__":
app.run(debug=True)
  1. Run the app and open it in a browser (so the request carries cookies).
  2. Type into the input to trigger the websocket=True callback.
  3. Observe ctx.cookies is {} and ctx.headers is empty.
  4. Change the callback to a normal HTTP callback (remove websocket=True) and observe the cookies/headers are present.

Expected behavior

callback_context.cookies and callback_context.headers (and args, path, remote, origin) should be populated for WebSocket callbacks just as they are for HTTP callbacks, so authentication/session helpers behave consistently across transports.

Actual behavior

callback_context.cookies/headers are empty for WebSocket callbacks, causing auth helpers such as dash_enterprise_auth.get_user_data() to fail.

Root cause

create_ws_context in dash/backends/ws.py builds the callback context but omits the request metadata that Dash._initialize_context sets for the HTTP path. The WebSocket handshake request (which carries the cookies/headers) is available in the backend WebSocket handlers (_fastapi.py / _quart.py) but is never forwarded into the context.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions