Merge pull request #143 from cartsnitch/betty/fix-session-cookie-parsing

fix(auth): parse compound Better-Auth cookie/bearer token
This commit is contained in:
cartsnitch-cto[bot]
2026-04-04 20:39:09 +00:00
committed by GitHub
2 changed files with 55 additions and 2 deletions
+5 -2
View File
@@ -71,11 +71,14 @@ async def get_current_user(
# 1. Check session cookie — prefer __Secure- variant (HTTPS) over plain (HTTP dev)
cookie_token = request.cookies.get(SECURE_SESSION_COOKIE_NAME) or request.cookies.get(SESSION_COOKIE_NAME)
if cookie_token:
token = cookie_token
# Better-Auth cookie format is "token.sessionId" — extract just the token part
token = cookie_token.split(".")[0] if "." in cookie_token else cookie_token
# 2. Fall back to Bearer header
if not token and credentials:
token = credentials.credentials
# Callers might pass the compound value here too
raw = credentials.credentials
token = raw.split(".")[0] if "." in raw else raw
if not token:
raise HTTPException(
+50
View File
@@ -71,6 +71,56 @@ async def test_delete_me(client, auth_headers):
assert resp.status_code == 404
@pytest.mark.asyncio
async def test_get_me_compound_cookie(client, db_engine):
"""Compound cookie value (token.sessionId) must be parsed to extract the token part."""
from tests.conftest import _create_test_user_and_session
_, session_token = await _create_test_user_and_session(
client, db_engine, email="compound@example.com", display_name="Compound User"
)
compound = f"{session_token}.B0atkJCFxK1rZlwWPMK97nVO2LnyDun7"
resp = await client.get(
"/auth/me",
headers={"Cookie": f"better-auth.session_token={compound}"},
)
assert resp.status_code == 200
assert resp.json()["email"] == "compound@example.com"
@pytest.mark.asyncio
async def test_get_me_raw_token_cookie(client, db_engine):
"""Raw token (no dot) in cookie must still work — regression guard."""
from tests.conftest import _create_test_user_and_session
_, session_token = await _create_test_user_and_session(
client, db_engine, email="rawcookie@example.com", display_name="Raw Cookie User"
)
resp = await client.get(
"/auth/me",
headers={"Cookie": f"better-auth.session_token={session_token}"},
)
assert resp.status_code == 200
assert resp.json()["email"] == "rawcookie@example.com"
@pytest.mark.asyncio
async def test_get_me_compound_bearer(client, db_engine):
"""Compound Bearer token (token.sessionId) must be parsed to extract the token part."""
from tests.conftest import _create_test_user_and_session
_, session_token = await _create_test_user_and_session(
client, db_engine, email="compoundbearer@example.com", display_name="Compound Bearer User"
)
compound = f"{session_token}.B0atkJCFxK1rZlwWPMK97nVO2LnyDun7"
resp = await client.get(
"/auth/me",
headers={"Authorization": f"Bearer {compound}"},
)
assert resp.status_code == 200
assert resp.json()["email"] == "compoundbearer@example.com"
@pytest.mark.asyncio
async def test_expired_session_rejected(client, db_engine):
"""Expired sessions must be rejected."""