fix: set session cookie in cookie jar instead of manual header
Using self._session.cookies.set() ensures the cookie is sent correctly by the requests session on all calls, including /api/auth/session. Also add sec-fetch-* headers required by chatgpt.com. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -38,30 +38,42 @@ class ChatGPTProvider(BaseProvider):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
self._session_token = token
|
self._session_token = token
|
||||||
|
|
||||||
|
# Set the session cookie in the cookie jar (proper cookie handling, not a raw header)
|
||||||
|
self._session.cookies.set(
|
||||||
|
"__Secure-next-auth.session-token",
|
||||||
|
token,
|
||||||
|
domain="chatgpt.com",
|
||||||
|
path="/",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Additional browser-like headers required by chatgpt.com
|
||||||
self._session.headers.update(
|
self._session.headers.update(
|
||||||
{
|
{
|
||||||
"Referer": "https://chatgpt.com/",
|
"Referer": "https://chatgpt.com/",
|
||||||
"Origin": "https://chatgpt.com",
|
"Origin": "https://chatgpt.com",
|
||||||
|
"sec-fetch-dest": "empty",
|
||||||
|
"sec-fetch-mode": "cors",
|
||||||
|
"sec-fetch-site": "same-origin",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
# Exchange the session cookie for an access token immediately
|
|
||||||
self._access_token: str = self._fetch_access_token(token)
|
# Exchange the session cookie for an access token
|
||||||
|
self._access_token: str = self._fetch_access_token()
|
||||||
self._session.headers["Authorization"] = f"Bearer {self._access_token}"
|
self._session.headers["Authorization"] = f"Bearer {self._access_token}"
|
||||||
logger.debug("[chatgpt] Session initialised — access token obtained (token: [REDACTED])")
|
logger.debug("[chatgpt] Session initialised — access token obtained (token: [REDACTED])")
|
||||||
|
|
||||||
def _fetch_access_token(self, session_token: str) -> str:
|
def _fetch_access_token(self) -> str:
|
||||||
"""Exchange the session cookie for a Bearer access token.
|
"""Exchange the session cookie for a Bearer access token.
|
||||||
|
|
||||||
Calls GET /api/auth/session with the session cookie, which returns
|
Calls GET /api/auth/session — the cookie jar already contains the
|
||||||
{"accessToken": "...", "user": {...}}.
|
session token, so no manual Cookie header is needed.
|
||||||
|
|
||||||
|
Returns {"accessToken": "...", "user": {...}}.
|
||||||
"""
|
"""
|
||||||
logger.debug("[chatgpt] Fetching access token from %s", AUTH_SESSION_URL)
|
logger.debug("[chatgpt] Fetching access token from %s", AUTH_SESSION_URL)
|
||||||
try:
|
try:
|
||||||
resp = self._session.get(
|
resp = self._session.get(AUTH_SESSION_URL, timeout=REQUEST_TIMEOUT)
|
||||||
AUTH_SESSION_URL,
|
|
||||||
headers={"Cookie": f"__Secure-next-auth.session-token={session_token}"},
|
|
||||||
timeout=REQUEST_TIMEOUT,
|
|
||||||
)
|
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -70,7 +82,7 @@ class ChatGPTProvider(BaseProvider):
|
|||||||
"fetch_access_token",
|
"fetch_access_token",
|
||||||
RuntimeError(
|
RuntimeError(
|
||||||
f"Could not exchange session token for access token: {e}. "
|
f"Could not exchange session token for access token: {e}. "
|
||||||
"Check that your CHATGPT_SESSION_TOKEN is current."
|
"Check that your CHATGPT_SESSION_TOKEN is current and not expired."
|
||||||
),
|
),
|
||||||
) from e
|
) from e
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user