How to get session in python envs using token ! #1823

Closed
opened 2026-03-13 09:05:45 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @vishnumallela on GitHub (Sep 1, 2025).

Problem : I have both frontend (where auth lives) and backend under same domain using nginx reverse proxy ! I designed in such a way that token is also send to my backend (fast-api) so that I can get/check session in backend also providing protected resource access!

Was not able to find a solution to get session using token in python envs !

Any help is appreciated ! Thanks !

Originally created by @vishnumallela on GitHub (Sep 1, 2025). Problem : I have both frontend (where auth lives) and backend under same domain using nginx reverse proxy ! I designed in such a way that token is also send to my backend (fast-api) so that I can get/check session in backend also providing protected resource access! Was not able to find a solution to get session using token in python envs ! Any help is appreciated ! Thanks !
GiteaMirror added the question label 2026-03-13 09:05:45 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 1, 2025):

You can validate a Better Auth session token in FastAPI by manually verifying the HMAC signature in Python. Here’s a function that does this:

import hashlib
import hmac
import base64
from urllib.parse import unquote

def verify_session_token(hmac_key: str, session_token: str) -> bool:
    try:
        parts = session_token.split('.')
        if len(parts) != 2:
            return False

        data_encoded = parts[0]
        signature_encoded = parts[1]

        # URL decode data and signature
        data = unquote(data_encoded)
        signature_expected_bytes = base64.urlsafe_b64decode(unquote(signature_encoded) + '=' * (4 - len(unquote(signature_encoded)) % 4))

        # Calculate HMAC-SHA256 signature
        hmac_obj = hmac.new(hmac_key.encode('utf-8'), data.encode('utf-8'), hashlib.sha256)
        signature_actual_bytes = hmac_obj.digest()

        # Compare signatures
        return hmac.compare_digest(signature_actual_bytes, signature_expected_bytes)

    except Exception:
        return False

You’ll need your Better Auth HMAC key to use this. There’s no official Python SDK, so this manual approach is currently the way to go for session validation in FastAPI reference.

If you’re using cookies for session tokens in a cross-origin setup, make sure to forward the cookie header from the frontend to your backend, and set cookies with sameSite: "none" and secure: true for things to work smoothly reference.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Sep 1, 2025): <!-- Answer --> You can validate a Better Auth session token in FastAPI by manually verifying the HMAC signature in Python. Here’s a function that does this: ```python import hashlib import hmac import base64 from urllib.parse import unquote def verify_session_token(hmac_key: str, session_token: str) -> bool: try: parts = session_token.split('.') if len(parts) != 2: return False data_encoded = parts[0] signature_encoded = parts[1] # URL decode data and signature data = unquote(data_encoded) signature_expected_bytes = base64.urlsafe_b64decode(unquote(signature_encoded) + '=' * (4 - len(unquote(signature_encoded)) % 4)) # Calculate HMAC-SHA256 signature hmac_obj = hmac.new(hmac_key.encode('utf-8'), data.encode('utf-8'), hashlib.sha256) signature_actual_bytes = hmac_obj.digest() # Compare signatures return hmac.compare_digest(signature_actual_bytes, signature_expected_bytes) except Exception: return False ``` You’ll need your Better Auth HMAC key to use this. There’s no official Python SDK, so this manual approach is currently the way to go for session validation in FastAPI [reference](https://github.com/better-auth/better-auth/issues/2685). If you’re using cookies for session tokens in a cross-origin setup, make sure to forward the cookie header from the frontend to your backend, and set cookies with `sameSite: "none"` and `secure: true` for things to work smoothly [reference](https://github.com/better-auth/better-auth/issues/4188). <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/9abaefc0-6e55-4487-87f7-6011ebb47cfc?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/9abaefc0-6e55-4487-87f7-6011ebb47cfc?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/9abaefc0-6e55-4487-87f7-6011ebb47cfc?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/9abaefc0-6e55-4487-87f7-6011ebb47cfc?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/9abaefc0-6e55-4487-87f7-6011ebb47cfc?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/9abaefc0-6e55-4487-87f7-6011ebb47cfc?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/9abaefc0-6e55-4487-87f7-6011ebb47cfc?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4352)
Author
Owner

@vishnumallela commented on GitHub (Sep 1, 2025):

Wow thanks ! 😀

@vishnumallela commented on GitHub (Sep 1, 2025): Wow thanks ! 😀
Author
Owner

@vishnumallela commented on GitHub (Sep 1, 2025):

@dosu i want to read user-id from token ! how ?

@vishnumallela commented on GitHub (Sep 1, 2025): @dosu i want to read user-id from token ! how ?
Author
Owner

@dosubot[bot] commented on GitHub (Sep 1, 2025):

The Better Auth session token is just a random string and doesn't contain the user-id directly. To get the user-id, you need to look up the session in your backend using the token—usually by querying your database or session store for a session where token == session_token, then reading the userId field from that session object (source).

If you use the session_data cookie, it contains a base64-encoded JSON payload with the session and user info. You can decode it in Python like this:

import base64
import json

def get_user_id_from_session_data(session_data_cookie):
    # Decode base64 (URL-safe, no padding)
    missing_padding = len(session_data_cookie) % 4
    if missing_padding:
        session_data_cookie += '=' * (4 - missing_padding)
    decoded = base64.urlsafe_b64decode(session_data_cookie)
    payload = json.loads(decoded)
    return payload['session']['user']['id']  # or payload['session']['userId']

# Example usage:
# user_id = get_user_id_from_session_data(request.cookies['session_data'])

This design keeps sensitive info out of the token itself for security (source).

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Sep 1, 2025): <!-- Answer --> The Better Auth session token is just a random string and doesn't contain the user-id directly. To get the user-id, you need to look up the session in your backend using the token—usually by querying your database or session store for a session where `token == session_token`, then reading the `userId` field from that session object ([source](https://github.com/better-auth/better-auth/blob/cf7f2f118147b6a79a99fcf48898408f038390f5/packages/better-auth/src/db/internal-adapter.ts)). If you use the `session_data` cookie, it contains a base64-encoded JSON payload with the session and user info. You can decode it in Python like this: ```python import base64 import json def get_user_id_from_session_data(session_data_cookie): # Decode base64 (URL-safe, no padding) missing_padding = len(session_data_cookie) % 4 if missing_padding: session_data_cookie += '=' * (4 - missing_padding) decoded = base64.urlsafe_b64decode(session_data_cookie) payload = json.loads(decoded) return payload['session']['user']['id'] # or payload['session']['userId'] # Example usage: # user_id = get_user_id_from_session_data(request.cookies['session_data']) ``` This design keeps sensitive info out of the token itself for security ([source](https://github.com/better-auth/better-auth/blob/cf7f2f118147b6a79a99fcf48898408f038390f5/packages/better-auth/src/cookies/index.ts)). <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/e98b0ad8-4e94-40db-aa2a-3f8c125bc51f?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/e98b0ad8-4e94-40db-aa2a-3f8c125bc51f?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/e98b0ad8-4e94-40db-aa2a-3f8c125bc51f?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/e98b0ad8-4e94-40db-aa2a-3f8c125bc51f?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/e98b0ad8-4e94-40db-aa2a-3f8c125bc51f?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/e98b0ad8-4e94-40db-aa2a-3f8c125bc51f?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/e98b0ad8-4e94-40db-aa2a-3f8c125bc51f?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4352)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1823