Refactor authentication cookie settings

This commit is contained in:
Gabriel Luiz Freitas Almeida 2024-02-19 11:45:36 -03:00
commit 2491c87fda
2 changed files with 68 additions and 11 deletions

View file

@ -1,7 +1,5 @@
from fastapi import APIRouter, Depends, HTTPException, Request, Response, status from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
from fastapi.security import OAuth2PasswordRequestForm from fastapi.security import OAuth2PasswordRequestForm
from sqlmodel import Session
from langflow.api.v1.schemas import Token from langflow.api.v1.schemas import Token
from langflow.services.auth.utils import ( from langflow.services.auth.utils import (
authenticate_user, authenticate_user,
@ -10,6 +8,7 @@ from langflow.services.auth.utils import (
create_user_tokens, create_user_tokens,
) )
from langflow.services.deps import get_session, get_settings_service from langflow.services.deps import get_session, get_settings_service
from sqlmodel import Session
router = APIRouter(tags=["Login"]) router = APIRouter(tags=["Login"])
@ -20,7 +19,9 @@ async def login_to_get_access_token(
form_data: OAuth2PasswordRequestForm = Depends(), form_data: OAuth2PasswordRequestForm = Depends(),
db: Session = Depends(get_session), db: Session = Depends(get_session),
# _: Session = Depends(get_current_active_user) # _: Session = Depends(get_current_active_user)
settings_service=Depends(get_settings_service),
): ):
auth_settings = settings_service.auth_settings
try: try:
user = authenticate_user(form_data.username, form_data.password, db) user = authenticate_user(form_data.username, form_data.password, db)
except Exception as exc: except Exception as exc:
@ -33,8 +34,20 @@ async def login_to_get_access_token(
if user: if user:
tokens = create_user_tokens(user_id=user.id, db=db, update_last_login=True) 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(
response.set_cookie("access_token_lf", tokens["access_token"], httponly=False, samesite="none", secure=True) "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 return tokens
else: else:
raise HTTPException( raise HTTPException(
@ -46,11 +59,20 @@ async def login_to_get_access_token(
@router.get("/auto_login") @router.get("/auto_login")
async def 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: if settings_service.auth_settings.AUTO_LOGIN:
tokens = create_user_longterm_token(db) 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 return tokens
raise HTTPException( raise HTTPException(
@ -63,12 +85,29 @@ async def auto_login(
@router.post("/refresh") @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") token = request.cookies.get("refresh_token_lf")
if token: if token:
tokens = create_refresh_token(token) tokens = create_refresh_token(token)
response.set_cookie("refresh_token_lf", tokens["refresh_token"], httponly=True, samesite="none", secure=True) response.set_cookie(
response.set_cookie("access_token_lf", tokens["access_token"], httponly=False, samesite="none", secure=True) "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 return tokens
else: else:
raise HTTPException( raise HTTPException(

View file

@ -2,7 +2,10 @@ import secrets
from pathlib import Path from pathlib import Path
from typing import Optional 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 langflow.services.settings.utils import read_secret_from_file, write_secret_to_file
from loguru import logger from loguru import logger
from passlib.context import CryptContext from passlib.context import CryptContext
@ -23,7 +26,9 @@ class AuthSettings(BaseSettings):
REFRESH_TOKEN_EXPIRE_MINUTES: int = 60 * 12 * 7 REFRESH_TOKEN_EXPIRE_MINUTES: int = 60 * 12 * 7
# API Key to execute /process endpoint # 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_KEY_ALGORITHM: str = "HS256"
API_V1_STR: str = "/api/v1" API_V1_STR: str = "/api/v1"
@ -34,6 +39,19 @@ class AuthSettings(BaseSettings):
SUPERUSER: str = DEFAULT_SUPERUSER SUPERUSER: str = DEFAULT_SUPERUSER
SUPERUSER_PASSWORD: str = DEFAULT_SUPERUSER_PASSWORD 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") pwd_context: CryptContext = CryptContext(schemes=["bcrypt"], deprecated="auto")
class Config: class Config: