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 import Request
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
from starlette.middleware.base import BaseHTTPMiddleware
|
from starlette.middleware.base import BaseHTTPMiddleware
|
||||||
@@ -34,6 +35,48 @@ class LoggingMiddleware(BaseHTTPMiddleware):
|
|||||||
|
|
||||||
return response
|
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):
|
async def log_request(self, request: Request, response,state):
|
||||||
try:
|
try:
|
||||||
headers = dict(request.headers)
|
headers = dict(request.headers)
|
||||||
@@ -43,13 +86,24 @@ class LoggingMiddleware(BaseHTTPMiddleware):
|
|||||||
else:
|
else:
|
||||||
path_template = request.url.path
|
path_template = request.url.path
|
||||||
|
|
||||||
db_operation = OperationLog(tenantid =request.state.tenant,
|
# 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,
|
clientip = request.client.host if request.client else None,
|
||||||
useragent =headers.get("user-agent", ""),
|
useragent =headers.get("user-agent", ""),
|
||||||
userid = request.state.user,
|
userid = request.state.user,
|
||||||
operation = request.method,
|
operation = request.method,
|
||||||
function = path_template,
|
function = path_template,
|
||||||
parameters = str({"path": request.path_params,"query": dict(request.query_params),"body": request.state.body}),
|
parameters = str({
|
||||||
|
"path": request.path_params,
|
||||||
|
"query": safe_query,
|
||||||
|
"body": safe_body
|
||||||
|
}),
|
||||||
response = f"status_code:{response.status_code }" )
|
response = f"status_code:{response.status_code }" )
|
||||||
|
|
||||||
db = request.state.db
|
db = request.state.db
|
||||||
@@ -71,5 +125,3 @@ class LoggingMiddleware(BaseHTTPMiddleware):
|
|||||||
async def write_log_to_db(self, db_operation,db):
|
async def write_log_to_db(self, db_operation,db):
|
||||||
db.add(db_operation)
|
db.add(db_operation)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user