From 4dfdb9032c910516be2d915acbbb1f72e70a4dbd Mon Sep 17 00:00:00 2001 From: Milin Date: Mon, 24 Mar 2025 14:34:31 +0800 Subject: [PATCH] feat(auth): Implement multi-user login support - Add an `accounts` dictionary in `AuthHandler` to store multiple user account information. - Modify login logic to support multiple user account verification. - Update environment variable example, add description for `AUTH_ACCOUNTS` variable. - Adjust authentication status check logic, use `auth_handler.accounts` to determine if authentication is configured. --- env.example | 11 +++++------ lightrag/api/auth.py | 11 ++++++++--- lightrag/api/lightrag_server.py | 13 ++++--------- lightrag/api/utils_api.py | 4 +--- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/env.example b/env.example index 46404582..ad8f0cd2 100644 --- a/env.example +++ b/env.example @@ -151,9 +151,8 @@ QDRANT_URL=http://localhost:16333 ### Redis REDIS_URI=redis://localhost:6379 -### For JWTt Auth -AUTH_USERNAME=admin # login name -AUTH_PASSWORD=admin123 # password -TOKEN_SECRET=your-key-for-LightRAG-API-Server # JWT key -TOKEN_EXPIRE_HOURS=4 # expire duration -WHITELIST_PATHS=/login,/health # white list +### For JWT Auth +# AUTH_ACCOUNTS='admin:admin123,user1:pass456' # username:password,username:password +# TOKEN_SECRET=Your-Key-For-LightRAG-API-Server # JWT key +# TOKEN_EXPIRE_HOURS=4 # expire duration +# WHITELIST_PATHS= # white list \ No newline at end of file diff --git a/lightrag/api/auth.py b/lightrag/api/auth.py index 5d9b00ac..b5533d20 100644 --- a/lightrag/api/auth.py +++ b/lightrag/api/auth.py @@ -20,9 +20,14 @@ class AuthHandler: self.secret = os.getenv("TOKEN_SECRET", "4f85ds4f56dsf46") self.algorithm = "HS256" self.expire_hours = int(os.getenv("TOKEN_EXPIRE_HOURS", 4)) - self.guest_expire_hours = int( - os.getenv("GUEST_TOKEN_EXPIRE_HOURS", 2) - ) # Guest token default expiration time + self.guest_expire_hours = int(os.getenv("GUEST_TOKEN_EXPIRE_HOURS", 2)) + + self.accounts = {} + auth_accounts = os.getenv("AUTH_ACCOUNTS") + if auth_accounts: + for account in auth_accounts.split(','): + username, password = account.split(':', 1) + self.accounts[username] = password def create_token( self, diff --git a/lightrag/api/lightrag_server.py b/lightrag/api/lightrag_server.py index 584d020f..e6193ed6 100644 --- a/lightrag/api/lightrag_server.py +++ b/lightrag/api/lightrag_server.py @@ -350,10 +350,8 @@ def create_app(args): @app.get("/auth-status", dependencies=[Depends(optional_api_key)]) async def get_auth_status(): """Get authentication status and guest token if auth is not configured""" - username = os.getenv("AUTH_USERNAME") - password = os.getenv("AUTH_PASSWORD") - if not (username and password): + if not auth_handler.accounts: # Authentication not configured, return guest token guest_token = auth_handler.create_token( username="guest", role="guest", metadata={"auth_mode": "disabled"} @@ -377,10 +375,7 @@ def create_app(args): @app.post("/login", dependencies=[Depends(optional_api_key)]) async def login(form_data: OAuth2PasswordRequestForm = Depends()): - username = os.getenv("AUTH_USERNAME") - password = os.getenv("AUTH_PASSWORD") - - if not (username and password): + if not auth_handler.accounts: # Authentication not configured, return guest token guest_token = auth_handler.create_token( username="guest", role="guest", metadata={"auth_mode": "disabled"} @@ -393,8 +388,8 @@ def create_app(args): "core_version": core_version, "api_version": __api_version__, } - - if form_data.username != username or form_data.password != password: + username = form_data.username + if auth_handler.accounts.get(username) != form_data.password: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect credentials" ) diff --git a/lightrag/api/utils_api.py b/lightrag/api/utils_api.py index 25136bd2..c3a49532 100644 --- a/lightrag/api/utils_api.py +++ b/lightrag/api/utils_api.py @@ -43,9 +43,7 @@ def get_auth_dependency(): token: str = Depends(OAuth2PasswordBearer(tokenUrl="login", auto_error=False)), ): # Check if authentication is configured - auth_configured = bool( - os.getenv("AUTH_USERNAME") and os.getenv("AUTH_PASSWORD") - ) + auth_configured = bool(auth_handler.accounts) # If authentication is not configured, skip all validation if not auth_configured: