1616
1717import io .github .timemachinelab .core .session .domain .entity .ConversationSession ;
1818import io .github .timemachinelab .core .session .infrastructure .web .dto .*;
19+ import io .github .timemachinelab .util .QaTreeSerializeUtil ;
1920import io .github .timemachinelab .entity .req .RetryRequest ;
2021import io .github .timemachinelab .entity .resp .ApiResult ;
2122import io .github .timemachinelab .entity .resp .RetryResponse ;
@@ -375,14 +376,24 @@ public ResponseEntity<ApiResult<ConversationHistoryResponse>> getConversationHis
375376 .body (ApiResult .error ("会话数据不完整" ));
376377 }
377378
378- // 4. 组装返回数据
379+ // 4. 序列化QaTree为前端期望的格式
380+ String serializedQaTree ;
381+ try {
382+ serializedQaTree = QaTreeSerializeUtil .serialize (qaTree );
383+ } catch (Exception e ) {
384+ log .error ("序列化QaTree失败 - sessionId: {}" , sessionId , e );
385+ return ResponseEntity .internalServerError ()
386+ .body (ApiResult .error ("序列化会话数据失败: " + e .getMessage ()));
387+ }
388+
389+ // 5. 组装返回数据
379390 ConversationHistoryResponse response = new ConversationHistoryResponse (
380391 session .getSessionId (),
381392 session .getUserId (),
382393 session .getCurrentNode (),
383394 session .getCreateTime (),
384395 session .getUpdateTime (),
385- qaTree
396+ serializedQaTree
386397 );
387398
388399 log .info ("成功获取对话历史 - sessionId: {}, 节点数量: {}" , sessionId , qaTree .getNodeCount ());
@@ -411,4 +422,59 @@ public ResponseEntity<Map<String, Object>> getSseStatus() {
411422 public ResponseEntity <Boolean > setUserProfile (@ RequestBody SetUserProfileRequest request ) {
412423 return ResponseEntity .ok (sessionManagementService .setUserProfile (request .getSessionId (), request .getUserId (), request .getUserProfile ()));
413424 }
425+
426+ /**
427+ * 验证指纹一致性
428+ * 检查客户端提供的指纹是否与服务端生成的指纹一致
429+ * 如果不一致,生成新的指纹替代客户端指纹,并返回空的sessionIdList避免水平越权
430+ *
431+ * @param request HTTP请求对象
432+ * @return 验证结果,包含是否一致和正确的指纹
433+ */
434+ @ PostMapping ("/validate-fingerprint" )
435+ public ResponseEntity <ApiResult <Map <String , Object >>> validateFingerprint (
436+ @ RequestBody Map <String , String > requestBody ,
437+ HttpServletRequest request ) {
438+
439+ try {
440+ // 从请求体中获取客户端指纹
441+ String clientFingerprint = requestBody .get ("fingerprint" );
442+
443+ // 生成服务端指纹
444+ UserFingerprint serverFingerprint = fingerprintService .getOrCreateUserFingerprint (request );
445+ String serverFingerprintId = serverFingerprint .getFingerprint ();
446+
447+ // 比较指纹
448+ boolean isConsistent = serverFingerprintId .equals (clientFingerprint );
449+
450+ Map <String , Object > result = new ConcurrentHashMap <>();
451+ result .put ("isConsistent" , isConsistent );
452+ result .put ("serverFingerprint" , serverFingerprintId );
453+ result .put ("clientFingerprint" , clientFingerprint );
454+ result .put ("timestamp" , System .currentTimeMillis ());
455+
456+ if (!isConsistent ) {
457+ log .warn ("指纹不一致 - 客户端: {}, 服务端: {}, 生成新指纹替代" , clientFingerprint , serverFingerprintId );
458+ result .put ("message" , "指纹不一致,已生成新指纹" );
459+ result .put ("newFingerprint" , serverFingerprintId );
460+ // 指纹不匹配时返回空的sessionIdList,避免水平越权
461+ result .put ("sessionIdList" , List .of ());
462+ result .put ("requireUpdate" , true );
463+ } else {
464+ log .debug ("指纹验证通过 - 指纹: {}" , serverFingerprintId );
465+ result .put ("message" , "指纹验证通过" );
466+ // 指纹匹配时返回对应的sessionIdList
467+ List <String > sessionIds = sessionManagementService .getUserSessionIds (serverFingerprintId );
468+ result .put ("sessionIdList" , sessionIds );
469+ result .put ("requireUpdate" , false );
470+ }
471+
472+ return ResponseEntity .ok (ApiResult .success (result ));
473+
474+ } catch (Exception e ) {
475+ log .error ("指纹验证失败: {}" , e .getMessage (), e );
476+ return ResponseEntity .internalServerError ()
477+ .body (ApiResult .error ("指纹验证失败: " + e .getMessage ()));
478+ }
479+ }
414480}
0 commit comments