160 lines
4.3 KiB
Go
160 lines
4.3 KiB
Go
package middleware
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
"verification-platform-backend/internal/database"
|
|
"verification-platform-backend/internal/model"
|
|
"verification-platform-backend/pkg/crypto"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type CryptoMiddleware struct {
|
|
cryptoManager *crypto.CryptoManager
|
|
shouldEncrypt bool
|
|
}
|
|
|
|
func NewCryptoMiddleware(encryptType crypto.EncryptType, secretKey string) *CryptoMiddleware {
|
|
shouldEncrypt := encryptType != crypto.EncryptTypeNone
|
|
return &CryptoMiddleware{
|
|
cryptoManager: crypto.NewCryptoManager(encryptType, secretKey),
|
|
shouldEncrypt: shouldEncrypt,
|
|
}
|
|
}
|
|
|
|
type EncryptedRequest struct {
|
|
Data string `json:"data" binding:"required"`
|
|
}
|
|
|
|
type EncryptedResponse struct {
|
|
Data string `json:"data"`
|
|
}
|
|
|
|
func (cm *CryptoMiddleware) ProcessRequest() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
contentType := c.GetHeader("Content-Type")
|
|
|
|
if strings.Contains(contentType, "application/json") {
|
|
body, err := io.ReadAll(c.Request.Body)
|
|
if err != nil {
|
|
c.JSON(400, gin.H{"code": 400, "message": "读取请求体失败"})
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
// 空请求体(如 GET 请求),跳过解析,直接放行
|
|
if len(body) > 0 {
|
|
var req interface{}
|
|
if err := json.Unmarshal(body, &req); err != nil {
|
|
c.JSON(400, gin.H{"code": 400, "message": "解析请求体失败"})
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
reqMap, ok := req.(map[string]interface{})
|
|
if ok {
|
|
if encryptedData, exists := reqMap["data"]; exists {
|
|
if dataStr, ok := encryptedData.(string); ok {
|
|
decrypted, err := cm.cryptoManager.Decrypt(dataStr)
|
|
if err != nil {
|
|
c.JSON(400, gin.H{"code": 400, "message": "解密失败: " + err.Error()})
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
var decryptedData interface{}
|
|
if err := json.Unmarshal([]byte(decrypted), &decryptedData); err != nil {
|
|
c.JSON(400, gin.H{"code": 400, "message": "解析解密数据失败"})
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
c.Set("decrypted_data", decryptedData)
|
|
c.Set("is_encrypted", true)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
|
|
}
|
|
|
|
c.Set("should_encrypt_response", cm.shouldEncrypt)
|
|
c.Set("crypto_manager", cm.cryptoManager)
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
func (cm *CryptoMiddleware) ProcessResponse() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
|
|
c.Writer = blw
|
|
|
|
c.Next()
|
|
|
|
shouldEncrypt := c.GetBool("should_encrypt_response")
|
|
fmt.Printf("[ProcessResponse] ShouldEncrypt: %v\n", shouldEncrypt)
|
|
|
|
if shouldEncrypt {
|
|
var response map[string]interface{}
|
|
if err := json.Unmarshal(blw.body.Bytes(), &response); err == nil {
|
|
responseJSON, _ := json.Marshal(response)
|
|
fmt.Printf("[ProcessResponse] Response to encrypt: %s\n", string(responseJSON))
|
|
|
|
var cryptoManager *crypto.CryptoManager
|
|
if cm, ok := c.Get("crypto_manager"); ok {
|
|
cryptoManager = cm.(*crypto.CryptoManager)
|
|
} else {
|
|
appKey := c.Param("appKey")
|
|
if appKey != "" {
|
|
var app model.Application
|
|
if err := database.DB.Where("app_key = ?", appKey).First(&app).Error; err == nil {
|
|
var encryptType crypto.EncryptType
|
|
switch app.EncryptType {
|
|
case "aes":
|
|
encryptType = crypto.EncryptTypeAES
|
|
case "rc4":
|
|
encryptType = crypto.EncryptTypeRC4
|
|
default:
|
|
encryptType = crypto.EncryptTypeNone
|
|
}
|
|
cryptoManager = crypto.NewCryptoManager(encryptType, app.EncryptKey)
|
|
}
|
|
}
|
|
}
|
|
|
|
if cryptoManager != nil {
|
|
encrypted, err := cryptoManager.Encrypt(string(responseJSON))
|
|
if err == nil {
|
|
encryptedResponse := EncryptedResponse{Data: encrypted}
|
|
encryptedJSON, _ := json.Marshal(encryptedResponse)
|
|
c.Writer.Header().Set("Content-Type", "application/json")
|
|
c.Writer.Write(encryptedJSON)
|
|
fmt.Printf("[ProcessResponse] Encrypted response sent\n")
|
|
return
|
|
} else {
|
|
fmt.Printf("[ProcessResponse] Encryption error: %v\n", err)
|
|
}
|
|
} else {
|
|
fmt.Printf("[ProcessResponse] CryptoManager is nil\n")
|
|
}
|
|
} else {
|
|
fmt.Printf("[ProcessResponse] JSON unmarshal error: %v\n", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
type bodyLogWriter struct {
|
|
gin.ResponseWriter
|
|
body *bytes.Buffer
|
|
}
|
|
|
|
func (w *bodyLogWriter) Write(b []byte) (int, error) {
|
|
return w.body.Write(b)
|
|
}
|