Skip to content

feat(auth): add cookie-based authentication for private/restricted video downloads#2

Open
Yinchaochen wants to merge 1 commit intosh13y:mainfrom
Yinchaochen:feat/cookie-auth-support
Open

feat(auth): add cookie-based authentication for private/restricted video downloads#2
Yinchaochen wants to merge 1 commit intosh13y:mainfrom
Yinchaochen:feat/cookie-auth-support

Conversation

@Yinchaochen
Copy link
Copy Markdown

Problem

Closes #1 — videos that require a Facebook login (friend-only posts, age-restricted reels, etc.) return "This video is private or not available for download" even when they are publicly visible to any logged-in user.

The root cause is that yt-dlp has no session context, so Facebook's CDN rejects the request.

Solution

Add optional cookie authentication in two modes:

1. Per-request cookies (for self-hosted / personal use)

Pass your browser cookies as a Netscape-format string in the cookies field:

curl -X POST http://localhost:8000/download \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.facebook.com/reel/2628095174202662/",
    "quality": "best",
    "cookies": "# Netscape HTTP Cookie File\n.facebook.com TRUE / FALSE 0 c_user 123456789\n..."
  }'

Export your cookies with the Get cookies.txt LOCALLY Chrome extension, then paste the file contents into the cookies field.

2. Server-side cookies file (for shared deployments)

Set the FB_COOKIES_FILE environment variable to a pre-exported cookies.txt path on the server. All requests will share that session without requiring callers to send cookies each time:

FB_COOKIES_FILE=/secrets/facebook_cookies.txt uvicorn app.main:app

Implementation

File Change
app/models.py Add optional cookies: str field to VideoDownloadRequest
app/config.py Add COOKIES_FILE setting backed by FB_COOKIES_FILE env var
app/services/video_service.py Resolve cookie source, write per-request cookies to a temp file, pass cookiefile to yt-dlp, delete temp file in finally
app/main.py Forward request.cookies to video_service in both /download and /info endpoints

Security notes

  • Per-request cookies are written to a tempfile, used for exactly one yt-dlp call, and deleted in a finally block — they are never stored on disk beyond the request lifetime.
  • The cookies field is optional and defaults to None; existing unauthenticated usage is unchanged.
  • The server-side FB_COOKIES_FILE path is never exposed in API responses.

Closes sh13y#1 — users can now download login-required or age-restricted
Facebook videos by supplying their browser cookies.

Two modes are supported:
- Per-request: pass a Netscape-format cookie string in the `cookies`
  field of the JSON body. The string is written to a temp file, used
  for that request only, and deleted immediately after.
- Server-side: set the FB_COOKIES_FILE env var to a cookies.txt path
  on the server. All requests share that session automatically.

Changes:
- models.py: add optional `cookies: str` field to VideoDownloadRequest
- config.py: add COOKIES_FILE setting backed by FB_COOKIES_FILE env var
- video_service.py: resolve cookie source in get_video_info(), pass
  cookiefile to _extract_info(), clean up temp file in finally block
- main.py: forward request.cookies to video_service in both /download
  and /info endpoints
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

How to use authenticated sessions

1 participant