moazx commited on
Commit
ef242c8
·
verified ·
1 Parent(s): 0f62f58

Update api/routers/auth.py

Browse files
Files changed (1) hide show
  1. api/routers/auth.py +17 -4
api/routers/auth.py CHANGED
@@ -5,11 +5,12 @@ import os
5
  import secrets
6
  from datetime import datetime, timedelta
7
  from typing import Dict, Optional
8
- from fastapi import APIRouter, HTTPException, Response, Cookie, Form
9
  from fastapi.responses import JSONResponse
10
  from pydantic import BaseModel
11
  from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired
12
  import logging
 
13
 
14
  logger = logging.getLogger(__name__)
15
 
@@ -92,6 +93,7 @@ def verify_credentials(username: str, password: str) -> bool:
92
  @router.post("/login", response_model=LoginResponse)
93
  async def login(
94
  response: Response,
 
95
  username: str = Form(...),
96
  password: str = Form(...)
97
  ):
@@ -107,13 +109,24 @@ async def login(
107
  token = create_session(username)
108
 
109
  # Set secure cookie
 
 
 
 
 
 
 
 
 
 
 
110
  response.set_cookie(
111
  key="session_token",
112
  value=token,
113
  httponly=True,
114
  max_age=SESSION_MAX_AGE,
115
- samesite="none",
116
- secure=True # Required for SameSite=None
117
  )
118
 
119
  logger.info(f"Successful login for user: {username}")
@@ -171,4 +184,4 @@ async def status(session_token: Optional[str] = Cookie(None)):
171
  return {
172
  "authenticated": session_data is not None,
173
  "username": session_data.get("username") if session_data else None
174
- }
 
5
  import secrets
6
  from datetime import datetime, timedelta
7
  from typing import Dict, Optional
8
+ from fastapi import APIRouter, HTTPException, Response, Cookie, Form, Request
9
  from fastapi.responses import JSONResponse
10
  from pydantic import BaseModel
11
  from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired
12
  import logging
13
+ from urllib.parse import urlparse
14
 
15
  logger = logging.getLogger(__name__)
16
 
 
93
  @router.post("/login", response_model=LoginResponse)
94
  async def login(
95
  response: Response,
96
+ request: Request,
97
  username: str = Form(...),
98
  password: str = Form(...)
99
  ):
 
109
  token = create_session(username)
110
 
111
  # Set secure cookie
112
+ # In development (HTTP), use lax samesite and secure=False
113
+ # In production (HTTPS), use none samesite and secure=True
114
+ is_production = os.getenv("ENVIRONMENT", "development") == "production"
115
+
116
+ origin = request.headers.get("origin")
117
+ parsed_origin = urlparse(origin) if origin else None
118
+ is_cross_site = bool(parsed_origin and parsed_origin.hostname and parsed_origin.hostname != request.url.hostname)
119
+ is_https = request.url.scheme == "https"
120
+ samesite = "none" if (is_https and (is_production or is_cross_site)) else "lax"
121
+ secure = True if samesite == "none" else is_production
122
+
123
  response.set_cookie(
124
  key="session_token",
125
  value=token,
126
  httponly=True,
127
  max_age=SESSION_MAX_AGE,
128
+ samesite=samesite,
129
+ secure=secure
130
  )
131
 
132
  logger.info(f"Successful login for user: {username}")
 
184
  return {
185
  "authenticated": session_data is not None,
186
  "username": session_data.get("username") if session_data else None
187
+ }