Auth must complete before accept()
The handshake is the only place to reject without leaving the client in an awkward "open then immediately closed" state. So all auth — token validation, permission checks, rate-limit-by-user — must happen before you call websocket.accept(). The cost of being strict here is zero; the cost of being lax is leaked auth state and confusing client UX.
FastAPI Depends works on WebSocket
The Depends(...) system is fully supported on WebSocket endpoints. You can write a dependency that extracts and validates the token, raising WebSocketException on failure, and the framework handles the close for you.
Cookies vs. tokens
If your users authenticate via session cookies in the browser, those cookies are sent automatically on the WebSocket upgrade GET. Read them via websocket.cookies. For non-browser clients (mobile, server-to-server), pass tokens in the query string. cwkPippa uses cookies for the WebUI and tokens for tooling — same auth code path, different transport.