I’m testing websockets to work with cookies and trying to get them in fast api. I manually installed them in chrome but I get an empty dictionary inside the application. I used the fast api documentation templates and slightly redesigned it
My html
JavaScript
x
44
44
1
html = """
2
<!DOCTYPE html>
3
<html>
4
<head>
5
<title>Chat</title>
6
</head>
7
<body>
8
<h1>WebSocket Chat</h1>
9
<form action="" onsubmit="sendMessage(event)">
10
<label>Item ID: <input type="text" id="itemId" autocomplete="off" value="foo"/></label>
11
<label>Token: <input type="text" id="token" autocomplete="off" value="some-key-token"/></label>
12
<button onclick="connect(event)">Connect</button>
13
<hr>
14
<label>Message: <input type="text" id="messageText" autocomplete="off"/></label>
15
<button>Send</button>
16
</form>
17
<ul id='messages'>
18
</ul>
19
<script>
20
var ws = null;
21
function connect(event) {
22
var itemId = "1000"
23
var token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI2MjlmYmU3ZGNjMzQxMGFiNWE2MmZkOWYiLCJ1c2VyIjoiQmk4eVVhOG5TS1dFRm8weEJjYWkwRUtDU2E3TyJ9.7hE3qIcFoLLoDqQSliaHXhSPs4FW75fNafumPdKHPmI"
24
ws = new WebSocket("ws://localhost:8000/ws/" + itemId + "/?token=" + token);
25
ws.onmessage = function(event) {
26
var messages = document.getElementById('messages')
27
var message = document.createElement('li')
28
var content = document.createTextNode(event.data)
29
message.appendChild(content)
30
messages.appendChild(message)
31
};
32
event.preventDefault()
33
}
34
function sendMessage(event) {
35
var input = document.getElementById("messageText")
36
ws.send(input.value)
37
input.value = ''
38
event.preventDefault()
39
}
40
</script>
41
</body>
42
</html>
43
"""
44
My websocket
JavaScript
1
41
41
1
class ConnectionManager:
2
def __init__(self):
3
self.active_connections: list = []
4
5
async def connect(self, websocket: WebSocket):
6
await websocket.accept()
7
self.active_connections.append(websocket)
8
9
def disconnect(self, websocket: WebSocket):
10
self.active_connections.remove(websocket)
11
12
async def send_personal_message(self, message: str, websocket: WebSocket):
13
await websocket.send_text(message)
14
15
async def broadcast(self, message: str):
16
for connection in self.active_connections:
17
await connection.send_text(message)
18
19
20
manager = ConnectionManager()
21
22
23
@app.websocket("/ws/{project_id}/")
24
async def test_websocket(websocket: WebSocket,
25
project_id: int,
26
token: str = Depends(authorization.get_user_websocket_token)
27
):
28
print(websocket.cookies)
29
await manager.connect(websocket)
30
try:
31
while True:
32
project = await db["storages"].find_one({"project_id": project_id})
33
if token in project["users"]:
34
print(True)
35
data = await websocket.receive_text()
36
await manager.send_personal_message(f"You wrote: {data}", websocket)
37
await manager.broadcast(f"Client says: {data}")
38
except WebSocketDisconnect:
39
manager.disconnect(websocket)
40
await manager.broadcast(f"Client left the chat")
41
print(websocket.cookies) returns an empty dictionary {}
Advertisement
Answer
Cookies are domain-defined, so you should point at localhost:8000 and there define that Cookie, not 127.0.0.1:8000.
Maybe it’s easier to check them in Postman.
They will be available at websocket.cookies
for sure.
websocket.cookies
under the hood checks Cookie
header:
JavaScript
1
11
11
1
@property
2
def cookies(self) -> typing.Dict[str, str]:
3
if not hasattr(self, "_cookies"):
4
cookies: typing.Dict[str, str] = {}
5
cookie_header = self.headers.get("cookie")
6
7
if cookie_header:
8
cookies = cookie_parser(cookie_header)
9
self._cookies = cookies
10
return self._cookies
11