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.
This commit is contained in:
Milin
2025-03-24 14:34:31 +08:00
parent e2737e4412
commit 4dfdb9032c
4 changed files with 18 additions and 21 deletions

View File

@@ -151,9 +151,8 @@ QDRANT_URL=http://localhost:16333
### Redis ### Redis
REDIS_URI=redis://localhost:6379 REDIS_URI=redis://localhost:6379
### For JWTt Auth ### For JWT Auth
AUTH_USERNAME=admin # login name # AUTH_ACCOUNTS='admin:admin123,user1:pass456' # username:password,username:password
AUTH_PASSWORD=admin123 # password # TOKEN_SECRET=Your-Key-For-LightRAG-API-Server # JWT key
TOKEN_SECRET=your-key-for-LightRAG-API-Server # JWT key # TOKEN_EXPIRE_HOURS=4 # expire duration
TOKEN_EXPIRE_HOURS=4 # expire duration # WHITELIST_PATHS= # white list
WHITELIST_PATHS=/login,/health # white list

View File

@@ -20,9 +20,14 @@ class AuthHandler:
self.secret = os.getenv("TOKEN_SECRET", "4f85ds4f56dsf46") self.secret = os.getenv("TOKEN_SECRET", "4f85ds4f56dsf46")
self.algorithm = "HS256" self.algorithm = "HS256"
self.expire_hours = int(os.getenv("TOKEN_EXPIRE_HOURS", 4)) self.expire_hours = int(os.getenv("TOKEN_EXPIRE_HOURS", 4))
self.guest_expire_hours = int( self.guest_expire_hours = int(os.getenv("GUEST_TOKEN_EXPIRE_HOURS", 2))
os.getenv("GUEST_TOKEN_EXPIRE_HOURS", 2)
) # Guest token default expiration time 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( def create_token(
self, self,

View File

@@ -350,10 +350,8 @@ def create_app(args):
@app.get("/auth-status", dependencies=[Depends(optional_api_key)]) @app.get("/auth-status", dependencies=[Depends(optional_api_key)])
async def get_auth_status(): async def get_auth_status():
"""Get authentication status and guest token if auth is not configured""" """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 # Authentication not configured, return guest token
guest_token = auth_handler.create_token( guest_token = auth_handler.create_token(
username="guest", role="guest", metadata={"auth_mode": "disabled"} username="guest", role="guest", metadata={"auth_mode": "disabled"}
@@ -377,10 +375,7 @@ def create_app(args):
@app.post("/login", dependencies=[Depends(optional_api_key)]) @app.post("/login", dependencies=[Depends(optional_api_key)])
async def login(form_data: OAuth2PasswordRequestForm = Depends()): async def login(form_data: OAuth2PasswordRequestForm = Depends()):
username = os.getenv("AUTH_USERNAME") if not auth_handler.accounts:
password = os.getenv("AUTH_PASSWORD")
if not (username and password):
# Authentication not configured, return guest token # Authentication not configured, return guest token
guest_token = auth_handler.create_token( guest_token = auth_handler.create_token(
username="guest", role="guest", metadata={"auth_mode": "disabled"} username="guest", role="guest", metadata={"auth_mode": "disabled"}
@@ -393,8 +388,8 @@ def create_app(args):
"core_version": core_version, "core_version": core_version,
"api_version": __api_version__, "api_version": __api_version__,
} }
username = form_data.username
if form_data.username != username or form_data.password != password: if auth_handler.accounts.get(username) != form_data.password:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect credentials" status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect credentials"
) )

View File

@@ -43,9 +43,7 @@ def get_auth_dependency():
token: str = Depends(OAuth2PasswordBearer(tokenUrl="login", auto_error=False)), token: str = Depends(OAuth2PasswordBearer(tokenUrl="login", auto_error=False)),
): ):
# Check if authentication is configured # Check if authentication is configured
auth_configured = bool( auth_configured = bool(auth_handler.accounts)
os.getenv("AUTH_USERNAME") and os.getenv("AUTH_PASSWORD")
)
# If authentication is not configured, skip all validation # If authentication is not configured, skip all validation
if not auth_configured: if not auth_configured: