比如有一个请求,需要先解密,返回的内容需要先加密
可以用gin.HandlerFunc
统一处理
// Data是加密的,需要统一解密传给后端业务处理
type Request struct {
AggEntityID string `json:"AggEntityId"`
Data string `json:"Data"`
TimeStamp string `json:"TimeStamp"` //yyyyMMddHHmmss
Seq string `json:"Seq"` //0001
Sig string `json:"Sig"` // 参数签名
}
// Data是明文的,需要统一加密返回给请求端
type Response struct {
Ret int32 `json:"Ret"`
Msg string `json:"Msg"`
Data string `json:"Data"`
Sig string `json:"Sig"`
}
统一处理
import (
"bytes"
"encoding/json"
"gitee.com/njderi/public-plat/internal/vpp/front-gateway/model"
"github.com/gin-gonic/gin"
"net/http"
)
// EncryptResponse 返回Response时先加密Data字段
func EncryptResponse() gin.HandlerFunc {
return func(c *gin.Context) {
// 创建一个缓冲区来捕获响应
w := &responseWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}
c.Writer = w
c.Next()
if c.Writer.Status() != http.StatusOK {
return
}
// 获取response
var res model.Response
if err := json.Unmarshal(w.body.Bytes(), &res); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read response body"})
return
}
// 修改response
res.Ret = 1
res.Msg = "Encrypted Response"
encryptedBody, err := json.Marshal(res)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to marshal encrypted response"})
return
}
// 修改response body
c.Writer = w.ResponseWriter
c.Writer.Header().Set("Content-Type", "application/json")
c.Writer.WriteHeader(http.StatusOK)
c.Writer.Write(encryptedBody)
}
}
type responseWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (w *responseWriter) Write(b []byte) (int, error) {
return w.body.Write(b)
}
import (
"bytes"
"encoding/json"
"gitee.com/njderi/public-plat/internal/vpp/front-gateway/model"
"github.com/gin-gonic/gin"
"io"
"io/ioutil"
"net/http"
)
// DecryptRequest 接收到Request后解密Data字段
func DecryptRequest() gin.HandlerFunc {
return func(c *gin.Context) {
if c.Request.Method == http.MethodPost || c.Request.Method == http.MethodPut {
body, err := io.ReadAll(c.Request.Body)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
c.Abort()
return
}
var req model.Request
if err := json.Unmarshal(body, &req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
c.Abort()
return
}
req.Data = "decrypt(req.Data, key)"
decryptedBody, err := json.Marshal(req)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to marshal decrypted request"})
c.Abort()
return
}
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(decryptedBody))
}
c.Next()
}
}
import (
"github.com/gin-gonic/gin"
)
func SetupAuthGroup(c *gin.Engine) {
authGroup := c.Group("/vpp/fg/v1")
// 这个group下所有的接口都会先解密,返回先加密
authGroup.Use(controller.DecryptRequest())
authGroup.Use(controller.EncryptResponse())
{
authGroup.POST("/query_token", controller.GetToken)
}
}