fix: 添加API请求签名支持
问题:认证管理器缺少签名头导致登录失败 修复:添加签名生成逻辑,与前端保持一致 - 使用crypto模块生成HMAC-SHA256签名 - 添加X-Signature、X-Timestamp、X-Nonce头 - 改进错误消息显示详细错误信息
This commit is contained in:
@@ -0,0 +1 @@
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; public class Test { public static void main(String[] args) { BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); String hash = "$2a$12$nZ1EMUpZQljbnEdIKzH72eHlDJKUmHmHppnTTVth/SlHs5VpSAr8C"; System.out.println("Match Test@123: " + encoder.matches("Test@123", hash)); } }
|
||||
@@ -1,14 +1,17 @@
|
||||
import { RoleFactory } from '../roles/role-factory';
|
||||
import crypto from 'crypto';
|
||||
|
||||
interface TokenCache {
|
||||
token: string;
|
||||
expiresAt: number;
|
||||
}
|
||||
|
||||
const SIGNATURE_SECRET = 'NovalonManageSystemSecretKey2026';
|
||||
|
||||
export class RoleAuthManager {
|
||||
private static tokenCache: Map<string, TokenCache> = new Map();
|
||||
private static readonly API_BASE_URL = process.env.VITE_API_BASE_URL || 'http://localhost:8084';
|
||||
private static readonly TOKEN_EXPIRY_BUFFER = 60000; // 1分钟缓冲
|
||||
private static readonly TOKEN_EXPIRY_BUFFER = 60000;
|
||||
|
||||
static async getRoleToken(roleName: string): Promise<string> {
|
||||
const cached = this.tokenCache.get(roleName);
|
||||
@@ -22,23 +25,54 @@ export class RoleAuthManager {
|
||||
|
||||
this.tokenCache.set(roleName, {
|
||||
token,
|
||||
expiresAt: Date.now() + 3600000 // 假设token有效期1小时
|
||||
expiresAt: Date.now() + 3600000
|
||||
});
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
private static generateSignatureHeaders(method: string, path: string, body: string): Record<string, string> {
|
||||
const timestamp = Date.now();
|
||||
const nonce = `${timestamp.toString(36)}-${Math.random().toString(36).substring(2, 15)}`;
|
||||
|
||||
const stringToSign = [
|
||||
method.toUpperCase(),
|
||||
path,
|
||||
'',
|
||||
body || '',
|
||||
timestamp.toString(),
|
||||
nonce
|
||||
].join('\n');
|
||||
|
||||
const signature = crypto
|
||||
.createHmac('sha256', SIGNATURE_SECRET)
|
||||
.update(stringToSign)
|
||||
.digest('base64');
|
||||
|
||||
return {
|
||||
'X-Signature': signature,
|
||||
'X-Timestamp': timestamp.toString(),
|
||||
'X-Nonce': nonce
|
||||
};
|
||||
}
|
||||
|
||||
private static async authenticateWithBackend(credentials: { username: string; password: string }): Promise<string> {
|
||||
const response = await fetch(`${this.API_BASE_URL}/api/auth/login`, {
|
||||
const path = '/api/auth/login';
|
||||
const body = JSON.stringify(credentials);
|
||||
const signatureHeaders = this.generateSignatureHeaders('POST', path, body);
|
||||
|
||||
const response = await fetch(`${this.API_BASE_URL}${path}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...signatureHeaders
|
||||
},
|
||||
body: JSON.stringify(credentials),
|
||||
body,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Authentication failed for user ${credentials.username}: ${response.statusText}`);
|
||||
const errorText = await response.text();
|
||||
throw new Error(`Authentication failed for user ${credentials.username}: ${response.statusText} - ${errorText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
Reference in New Issue
Block a user