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:
11
env.example
11
env.example
@@ -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
|
|
@@ -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,
|
||||||
|
@@ -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"
|
||||||
)
|
)
|
||||||
|
@@ -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:
|
||||||
|
Reference in New Issue
Block a user