Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Requests seems not to send the session cookie back to the server #6534

Closed
flixman opened this issue Sep 21, 2023 · 1 comment
Closed

Requests seems not to send the session cookie back to the server #6534

flixman opened this issue Sep 21, 2023 · 1 comment

Comments

@flixman
Copy link

flixman commented Sep 21, 2023

I have a flask application, and I want to interact with it through requests. To this end, I have coded a small script providing a client that is supposed to keep around jwt and CSFR tokens that are sent back by the server:

from http import HTTPStatus
from typing import Callable

import requests
from requests import Response


class AuthenticatedClient:
    def __init__(self, base_url: str, email: str, password: str):
        self._client = requests.Session()
        self._base_url = base_url.rstrip('/')
        response = self.post('/api/auth/login', json=dict(email=email, password=password))
        if response.status_code != HTTPStatus.OK:
            raise RuntimeError('Authentication did not succeed')

    def _get_csfr(self, kwargs) -> None:
        response = self._client.get(f'{self._base_url}/api/csrf')
        kwargs['headers'] = kwargs.get('headers', {}) | {'X-CSRF-Token': response.json()['csrf']}

    def _action(self, method: Callable, url: str, *args, **kwargs) -> Response:
        url = url.lstrip('/')
        return method(f'{self._base_url}/{url}', *args, **kwargs)

    def get(self, url, *args, **kwargs) -> Response:
        return self._action(self._client.get, url, *args, **kwargs)

    def put(self, url, *args, **kwargs) -> Response:
        self._get_csfr(kwargs)
        return self._action(self._client.put, url, *args, **kwargs)

    def post(self, url, *args, **kwargs) -> Response:
        self._get_csfr(kwargs)
        return self._action(self._client.post, url, *args, **kwargs)

    def delete(self, url, *args, **kwargs) -> Response:
        self._get_csfr(kwargs)
        return self._action(self._client.delete, url, *args, **kwargs)

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._client.close()


if __name__ == "__main__":

    credentials = dict(email='myuser@email.com', password='mypassword')

    # get an authenticated client
    with AuthenticatedClient('http://127.0.0.1:5000', **credentials) as client:
        # get all the lists for the user, and request their deletion
        lists = client.get('/api/todolists')

Expected Result

I would expect to get something back on the "lists" variable, given that the credentials are correct.

Actual Result

I am getting an error due to the CSRF validation. Upon inspection of the trace with wireshark, I can conclude that the session cookie is being received and stored when doing the get for the CSRF token, but is not sent with the POST request when the AuthenticatedClient object is initialized.

System Information

$ python -m requests.help
{
  "chardet": {
    "version": null
  },
  "charset_normalizer": {
    "version": "3.2.0"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "3.4"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.11.5"
  },
  "platform": {
    "release": "6.5.3-arch1-1",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.31.0"
  },
  "system_ssl": {
    "version": "30100020"
  },
  "urllib3": {
    "version": "2.0.4"
  },
  "using_charset_normalizer": true,
  "using_pyopenssl": false
}
@sigmavirus24
Copy link
Contributor

Duplicate of #6344 and so many more

In the future, please search closed and open issues before creating new ones that are duplicates.

@sigmavirus24 sigmavirus24 closed this as not planned Won't fix, can't repro, duplicate, stale Sep 21, 2023
@psf psf locked and limited conversation to collaborators Sep 21, 2023
@psf psf unlocked this conversation Sep 21, 2023
@psf psf locked and limited conversation to collaborators Sep 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants