Merged PR 164: BUG916:ユーザーのパスワードをログに出さないようにする
BUG916:ユーザーのパスワードをログに出さないようにする Related work items: #916
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
|
||||
from urllib.parse import parse_qs, urlencode
|
||||
from fastapi import Request
|
||||
from fastapi.responses import JSONResponse
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
@@ -33,6 +34,48 @@ class LoggingMiddleware(BaseHTTPMiddleware):
|
||||
await self.log_request(request, response,state)
|
||||
|
||||
return response
|
||||
|
||||
def sanitize_password(self,data):
|
||||
"""
|
||||
データ内の password パラメータをフィルタリングする機能。
|
||||
dict、JSON 文字列、URL エンコード文字列、QueryDict をサポート。
|
||||
"""
|
||||
if data is None:
|
||||
return data
|
||||
elif isinstance(data, dict):
|
||||
data.pop('password', None)
|
||||
return data
|
||||
elif isinstance(data, list):
|
||||
return [self.sanitize_password(item) for item in data]
|
||||
elif isinstance(data, (str, bytes)):
|
||||
if isinstance(data, bytes):
|
||||
data = data.decode('utf-8') # bytes to str
|
||||
# JSON解析
|
||||
try:
|
||||
parsed_json = json.loads(data)
|
||||
sanitized_json = self.sanitize_password(parsed_json)
|
||||
return json.dumps(sanitized_json, separators=(',', ':'))
|
||||
except json.JSONDecodeError:
|
||||
# URL 解析
|
||||
try:
|
||||
parsed_dict = parse_qs(data)
|
||||
parsed_dict.pop('password', None)
|
||||
return urlencode(parsed_dict, doseq=True)
|
||||
except:
|
||||
parts = data.split('&')
|
||||
filtered_parts = []
|
||||
for part in parts:
|
||||
if '=' in part:
|
||||
key, _ = part.split('=', 1)
|
||||
if key == 'password':
|
||||
continue
|
||||
filtered_parts.append(part)
|
||||
return '&'.join(filtered_parts)
|
||||
# QueryDict 例えば FastAPI の request.query_params)
|
||||
elif hasattr(data, 'items'):
|
||||
return {k: v for k, v in data.items() if k != 'password'}
|
||||
return data
|
||||
|
||||
|
||||
async def log_request(self, request: Request, response,state):
|
||||
try:
|
||||
@@ -42,15 +85,26 @@ class LoggingMiddleware(BaseHTTPMiddleware):
|
||||
path_template = route.path
|
||||
else:
|
||||
path_template = request.url.path
|
||||
|
||||
db_operation = OperationLog(tenantid =request.state.tenant,
|
||||
clientip = request.client.host if request.client else None,
|
||||
useragent =headers.get("user-agent", ""),
|
||||
userid = request.state.user,
|
||||
operation = request.method,
|
||||
function = path_template,
|
||||
parameters = str({"path": request.path_params,"query": dict(request.query_params),"body": request.state.body}),
|
||||
response = f"status_code:{response.status_code }" )
|
||||
|
||||
# passwordのパラメータを除外する
|
||||
safe_query = self.sanitize_password(request.query_params.items())
|
||||
|
||||
# passwordのパラメータを除外する
|
||||
safe_body = self.sanitize_password(request.state.body)
|
||||
|
||||
db_operation = OperationLog(
|
||||
tenantid =request.state.tenant,
|
||||
clientip = request.client.host if request.client else None,
|
||||
useragent =headers.get("user-agent", ""),
|
||||
userid = request.state.user,
|
||||
operation = request.method,
|
||||
function = path_template,
|
||||
parameters = str({
|
||||
"path": request.path_params,
|
||||
"query": safe_query,
|
||||
"body": safe_body
|
||||
}),
|
||||
response = f"status_code:{response.status_code }" )
|
||||
|
||||
db = request.state.db
|
||||
if db:
|
||||
@@ -71,5 +125,3 @@ class LoggingMiddleware(BaseHTTPMiddleware):
|
||||
async def write_log_to_db(self, db_operation,db):
|
||||
db.add(db_operation)
|
||||
db.commit()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user