diff --git a/src/backend/langflow/api/v1/login.py b/src/backend/langflow/api/v1/login.py index e867839dd..1bd3dd55b 100644 --- a/src/backend/langflow/api/v1/login.py +++ b/src/backend/langflow/api/v1/login.py @@ -1,7 +1,5 @@ from fastapi import APIRouter, Depends, HTTPException, Request, Response, status from fastapi.security import OAuth2PasswordRequestForm -from sqlmodel import Session - from langflow.api.v1.schemas import Token from langflow.services.auth.utils import ( authenticate_user, @@ -10,6 +8,7 @@ from langflow.services.auth.utils import ( create_user_tokens, ) from langflow.services.deps import get_session, get_settings_service +from sqlmodel import Session router = APIRouter(tags=["Login"]) @@ -20,7 +19,9 @@ async def login_to_get_access_token( form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_session), # _: Session = Depends(get_current_active_user) + settings_service=Depends(get_settings_service), ): + auth_settings = settings_service.auth_settings try: user = authenticate_user(form_data.username, form_data.password, db) except Exception as exc: @@ -33,8 +34,20 @@ async def login_to_get_access_token( if user: tokens = create_user_tokens(user_id=user.id, db=db, update_last_login=True) - response.set_cookie("refresh_token_lf", tokens["refresh_token"], httponly=True, samesite="none", secure=True) - response.set_cookie("access_token_lf", tokens["access_token"], httponly=False, samesite="none", secure=True) + response.set_cookie( + "refresh_token_lf", + tokens["refresh_token"], + httponly=auth_settings.REFRESH_TOKEN_HTTPONLY, + samesite=auth_settings.REFRESH_SAME_SITE, + secure=auth_settings.REFRESH_SECURE, + ) + response.set_cookie( + "access_token_lf", + tokens["access_token"], + httponly=auth_settings.ACCESS_HTTPONLY, + samesite=auth_settings.ACCESS_SAME_SITE, + secure=auth_settings.ACCESS_SECURE, + ) return tokens else: raise HTTPException( @@ -46,11 +59,20 @@ async def login_to_get_access_token( @router.get("/auto_login") async def auto_login( - response: Response, db: Session = Depends(get_session), settings_service=Depends(get_settings_service) + response: Response, + db: Session = Depends(get_session), + settings_service=Depends(get_settings_service), ): + auth_settings = settings_service.auth_settings if settings_service.auth_settings.AUTO_LOGIN: tokens = create_user_longterm_token(db) - response.set_cookie("access_token_lf", tokens["access_token"], httponly=False, samesite="none", secure=True) + response.set_cookie( + "access_token_lf", + tokens["access_token"], + httponly=auth_settings.ACCESS_HTTPONLY, + samesite=auth_settings.ACCESS_SAME_SITE, + secure=auth_settings.ACCESS_SECURE, + ) return tokens raise HTTPException( @@ -63,12 +85,29 @@ async def auto_login( @router.post("/refresh") -async def refresh_token(request: Request, response: Response): +async def refresh_token( + request: Request, response: Response, settings_service=Depends(get_settings_service) +): + auth_settings = settings_service.auth_settings + token = request.cookies.get("refresh_token_lf") + if token: tokens = create_refresh_token(token) - response.set_cookie("refresh_token_lf", tokens["refresh_token"], httponly=True, samesite="none", secure=True) - response.set_cookie("access_token_lf", tokens["access_token"], httponly=False, samesite="none", secure=True) + response.set_cookie( + "refresh_token_lf", + tokens["refresh_token"], + httponly=auth_settings.REFRESH_TOKEN_HTTPONLY, + samesite=auth_settings.REFRESH_SAME_SITE, + secure=auth_settings.REFRESH_SECURE, + ) + response.set_cookie( + "access_token_lf", + tokens["access_token"], + httponly=auth_settings.ACCESS_HTTPONLY, + samesite=auth_settings.ACCESS_SAME_SITE, + secure=auth_settings.ACCESS_SECURE, + ) return tokens else: raise HTTPException( diff --git a/src/backend/langflow/services/settings/auth.py b/src/backend/langflow/services/settings/auth.py index 92a696cc5..258ff5f63 100644 --- a/src/backend/langflow/services/settings/auth.py +++ b/src/backend/langflow/services/settings/auth.py @@ -2,7 +2,10 @@ import secrets from pathlib import Path from typing import Optional -from langflow.services.settings.constants import DEFAULT_SUPERUSER, DEFAULT_SUPERUSER_PASSWORD +from langflow.services.settings.constants import ( + DEFAULT_SUPERUSER, + DEFAULT_SUPERUSER_PASSWORD, +) from langflow.services.settings.utils import read_secret_from_file, write_secret_to_file from loguru import logger from passlib.context import CryptContext @@ -23,7 +26,9 @@ class AuthSettings(BaseSettings): REFRESH_TOKEN_EXPIRE_MINUTES: int = 60 * 12 * 7 # API Key to execute /process endpoint - API_KEY_SECRET_KEY: Optional[str] = "b82818e0ad4ff76615c5721ee21004b07d84cd9b87ba4d9cb42374da134b841a" + API_KEY_SECRET_KEY: Optional[str] = ( + "b82818e0ad4ff76615c5721ee21004b07d84cd9b87ba4d9cb42374da134b841a" + ) API_KEY_ALGORITHM: str = "HS256" API_V1_STR: str = "/api/v1" @@ -34,6 +39,19 @@ class AuthSettings(BaseSettings): SUPERUSER: str = DEFAULT_SUPERUSER SUPERUSER_PASSWORD: str = DEFAULT_SUPERUSER_PASSWORD + REFRESH_SAME_SITE: str = "none" + """The SameSite attribute of the refresh token cookie.""" + REFRESH_SECURE: bool = True + """The Secure attribute of the refresh token cookie.""" + REFRESH_HTTPONLY: bool = True + """The HttpOnly attribute of the refresh token cookie.""" + ACCESS_SAME_SITE: str = "none" + """The SameSite attribute of the access token cookie.""" + ACCESS_SECURE: bool = True + """The Secure attribute of the access token cookie.""" + ACCESS_HTTPONLY: bool = False + """The HttpOnly attribute of the access token cookie.""" + pwd_context: CryptContext = CryptContext(schemes=["bcrypt"], deprecated="auto") class Config: