Skip to content

sanic-jwt cookie configuration broken in Sanic 24.12.0 Due to deprecated response.cookies API #276

@MaxenRace

Description

@MaxenRace

In Sanic version 24.12.0, the outdated approach to cookie configuration prevents the login functionality from working properly.

Error log:

INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
/home/penta/Python/video_website/.venv/lib/python3.12/site-packages/sanic_jwt/authentication.py:60: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
exp = datetime.utcnow() + delta
Main 2025-02-28 14:28:56 +0800 ERROR: Exception occurred while handling uri: 'http://127.0.0.1:8000/api/auth'
Traceback (most recent call last):
File "handle_request", line 100, in handle_request
Extend = TypeVar("Extend", type) # type: ignore
^^^^^^^^^^^^^^
File "/home/penta/Python/video_website/.venv/lib/python3.12/site-packages/sanic_jwt/endpoints.py", line 58, in post
resp = self.responses.get_token_response(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/penta/Python/video_website/.venv/lib/python3.12/site-packages/sanic_jwt/responses.py", line 61, in get_token_response
_set_cookie(response, key, access_token, config)
File "/home/penta/Python/video_website/.venv/lib/python3.12/site-packages/sanic_jwt/responses.py", line 15, in _set_cookie
response.cookies[key] = value
~~~~~~~~~~~~~~~~^^^^^
TypeError: 'CookieJar' object does not support item assignment
INFO: 127.0.0.1:0 - "POST /api/auth HTTP/1.1" 500 Internal Server Error

The _set_cookie function in the response.py file uses a deprecated method.
The response.cookies can no longer be directly modified – cookie settings must be applied through the add_cookie method.

def _set_cookie(response, key, value, config, force_httponly=None):
    response.cookies[key] = value
    response.cookies[key]["httponly"] = (
        config.cookie_httponly() if force_httponly is None else force_httponly
    )
    response.cookies[key]["path"] = config.cookie_path()

    for item, option in COOKIE_OPTIONS:
        value = getattr(config, option)()
        if value:
            response.cookies[key][item] = value

I modified this file, and it works:

def _set_cookie(response: JSONResponse, key, value, config, force_httponly=None):
    opts = {}   # options for cookie
    for item, option in COOKIE_OPTIONS:
        opt_value = getattr(config, option)()
        if opt_value:
            opts[item] = opt_value
    
    opts["secure"] = config.cookie_secure() 

    response.add_cookie(
        key,
        value,
        httponly=config.cookie_httponly() if force_httponly is None else force_httponly,
        path=config.cookie_path(),
        **opts
    )

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions