Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create websocket connection from requests session in python

I need to receive data from a website over a websocket connection. Access to the websocket is only given after logging into the website. Using a session in python requests I am able to post my login information to the login page and authenticate my details. Websocket-client would be used for the creating the websocket connection to the website however the websocket connection created would not be through the login session.

How can I create a websocket connection after logging in through requests?

I found a similiar question here but it has not been answered Python - Websockets Unable to validate my session

This is my code so far (simplified a bit).

import requests
from bs4 import BeautifulSoup
import base64
import random
import websocket

headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'}

payload = {
    'username': 'username',
    'password': 'password'}

session = requests.Session()

r = session.get("https://www.example.com/login", headers=headers)

soup = BeautifulSoup(r.content, 'html.parser')
payload['token'] = soup.find('input', attrs={'name': 'token'})['value']

r = session.post("https://www.example.com/login", data=payload, headers=headers)
r = session.get("https://www.example.com/", headers=headers)

headers['Sec-WebSocket-Key'] = str(base64.b64encode(bytes([random.randint(0, 255) for _ in range(16)])), 'ascii')
headers['Sec-WebSocket-Version'] = '13'
headers['Upgrade'] = 'websocket'

ws = websocket.WebSocketApp('wss://www.example.com/streaming/',
                            header=headers,
                            #session=session????)
ws.run_forever()
like image 943
None Avatar asked Nov 14 '19 21:11

None


1 Answers

After much searching I eventually found the source of the problem. I was using Chrome Dev Tools to view the network packets when accessing the website through chrome browser, however Chrome Dev Tools does not show cookies for a websocket request. Firefox Developer Tools does show the cookies for a websocket request and I only discovered what cookies were being sent when I used Firefox. The solution is to extract the cookies for the Requests Session, and pass these cookies to the WebSocketApp. That way the websocket server can verify you are logged in.

cookies = session.cookies.get_dict()
ws = websocket.WebSocketApp('wss://www.example.com/streaming/',
                        header=headers,
                        cookie="; ".join(["%s=%s" %(i, j) for i, j in cookies.items()]))
like image 107
None Avatar answered Nov 07 '22 21:11

None