feat: 统一JWT密钥配置并修复签名验证问题
修复前端签名生成中bodyString硬编码问题 添加start-frontend.sh脚本启动前端服务 统一manage-app和gateway的JWT密钥配置 修复Repository扫描路径问题 更新测试配置和依赖 重构表名映射为sys_user和sys_role 完善用户实体类字段映射 添加集成测试配置和测试用例
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
"""
|
||||
测试前后端签名验证
|
||||
"""
|
||||
|
||||
import hmac
|
||||
import hashlib
|
||||
import base64
|
||||
import time
|
||||
import requests
|
||||
|
||||
def generate_signature(method, path, query='', body='', timestamp=None, nonce=None):
|
||||
"""生成签名(模拟后端逻辑)"""
|
||||
if timestamp is None:
|
||||
timestamp = int(time.time() * 1000)
|
||||
if nonce is None:
|
||||
nonce = f"{int(time.time())}-test123"
|
||||
|
||||
secret = 'NovalonManageSystemSecretKey2026'
|
||||
|
||||
string_to_sign = '\n'.join([
|
||||
method,
|
||||
path,
|
||||
query or '',
|
||||
body or '',
|
||||
str(timestamp),
|
||||
nonce
|
||||
])
|
||||
|
||||
print(f"签名字符串:\n{string_to_sign}")
|
||||
print(f"\n签名字符串长度: {len(string_to_sign)}")
|
||||
|
||||
signature = hmac.new(
|
||||
secret.encode('utf-8'),
|
||||
string_to_sign.encode('utf-8'),
|
||||
hashlib.sha256
|
||||
).digest()
|
||||
|
||||
signature_base64 = base64.b64encode(signature).decode('utf-8')
|
||||
|
||||
return signature_base64, timestamp, nonce
|
||||
|
||||
def test_signature():
|
||||
"""测试签名验证"""
|
||||
print("=" * 60)
|
||||
print("测试前后端签名验证")
|
||||
print("=" * 60)
|
||||
|
||||
# 测试1: 登录接口(在白名单中,不需要签名)
|
||||
print("\n测试1: 登录接口(白名单)")
|
||||
login_data = {
|
||||
"username": "admin",
|
||||
"password": "admin123"
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
'http://localhost:8080/api/auth/login',
|
||||
json=login_data
|
||||
)
|
||||
|
||||
print(f"状态码: {response.status_code}")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
token = data.get('token')
|
||||
print(f"✅ 登录成功,获取token: {token[:50]}...")
|
||||
else:
|
||||
print(f"❌ 登录失败: {response.text}")
|
||||
return
|
||||
|
||||
# 测试2: 用户列表接口(需要签名)
|
||||
print("\n测试2: 用户列表接口(需要签名)")
|
||||
|
||||
method = 'GET'
|
||||
path = '/api/users/page'
|
||||
query = 'page=0&size=10&sortBy=id&sortOrder=asc'
|
||||
body = ''
|
||||
|
||||
signature, timestamp, nonce = generate_signature(method, path, query, body)
|
||||
|
||||
print(f"\n生成的签名: {signature}")
|
||||
print(f"时间戳: {timestamp}")
|
||||
print(f"Nonce: {nonce}")
|
||||
|
||||
headers = {
|
||||
'Authorization': f'Bearer {token}',
|
||||
'X-Signature': signature,
|
||||
'X-Timestamp': str(timestamp),
|
||||
'X-Nonce': nonce,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
url = f'http://localhost:8080{path}?{query}'
|
||||
print(f"\n请求URL: {url}")
|
||||
print(f"请求头:")
|
||||
for key, value in headers.items():
|
||||
if key in ['X-Signature', 'Authorization']:
|
||||
print(f" {key}: {value[:30]}...")
|
||||
else:
|
||||
print(f" {key}: {value}")
|
||||
|
||||
response = requests.get(url, headers=headers)
|
||||
|
||||
print(f"\n响应状态码: {response.status_code}")
|
||||
if response.status_code == 200:
|
||||
print(f"✅ 签名验证成功")
|
||||
data = response.json()
|
||||
print(f"返回数据: {str(data)[:100]}...")
|
||||
else:
|
||||
print(f"❌ 签名验证失败")
|
||||
print(f"响应内容: {response.text}")
|
||||
|
||||
# 测试3: 不带签名的请求
|
||||
print("\n测试3: 不带签名的请求")
|
||||
headers_no_sig = {
|
||||
'Authorization': f'Bearer {token}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.get(url, headers=headers_no_sig)
|
||||
print(f"响应状态码: {response.status_code}")
|
||||
print(f"响应内容: {response.text[:200]}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_signature()
|
||||
Reference in New Issue
Block a user