|
@@ -0,0 +1,82 @@
|
|
|
+package routers
|
|
|
+
|
|
|
+import (
|
|
|
+ "ColdVerify_server/conf"
|
|
|
+ "ColdVerify_server/controllers"
|
|
|
+ "ColdVerify_server/lib"
|
|
|
+ "ColdVerify_server/logs"
|
|
|
+ "crypto/hmac"
|
|
|
+ "crypto/sha256"
|
|
|
+ "encoding/hex"
|
|
|
+ "errors"
|
|
|
+ beego "github.com/beego/beego/v2/server/web"
|
|
|
+ "github.com/beego/beego/v2/server/web/context"
|
|
|
+ "strconv"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+const apiKeyHeader = "X-API-KEY"
|
|
|
+const apiSignatureHeader = "X-API-SIGNATURE"
|
|
|
+const apiTimestampHeader = "X-API-TIMESTAMP"
|
|
|
+
|
|
|
+func isValidSignature(apiKey, signature, timestamp string) bool {
|
|
|
+ // 使用提供的 API Key 查找对应的 API Secret
|
|
|
+ if apiKey != conf.OpenApi_Key {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ secret := conf.OpenApi_Secret
|
|
|
+
|
|
|
+ // 计算签名,签名内容是 "apiKey + timestamp"
|
|
|
+ message := apiKey + timestamp
|
|
|
+ mac := hmac.New(sha256.New, []byte(secret))
|
|
|
+ mac.Write([]byte(message))
|
|
|
+ expectedSignature := hex.EncodeToString(mac.Sum(nil))
|
|
|
+ logs.Println("apiKey:", apiKey)
|
|
|
+ logs.Println("secret:", secret)
|
|
|
+ logs.Println("时间戳:", timestamp)
|
|
|
+ logs.Println("生成的签名:", expectedSignature)
|
|
|
+ logs.Println("传递的签名:", signature)
|
|
|
+ // 验证客户端提供的签名是否与预期签名匹配
|
|
|
+ return hmac.Equal([]byte(signature), []byte(expectedSignature))
|
|
|
+}
|
|
|
+func ApiKeyAuthMiddleware(ctx *context.Context) {
|
|
|
+ apiKey := ctx.Input.Query(apiKeyHeader)
|
|
|
+ signature := ctx.Input.Query(apiSignatureHeader)
|
|
|
+ timestamp := ctx.Input.Query(apiTimestampHeader)
|
|
|
+
|
|
|
+ // 检查 API Key, 签名和时间戳是否存在
|
|
|
+ if apiKey == "" || signature == "" || timestamp == "" {
|
|
|
+ err := errors.New("API Key, Signature, and Timestamp required")
|
|
|
+ data := lib.JSONS{Code: 202, Msg: err.Error()}
|
|
|
+ ctx.Output.JSON(data, true, false)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验请求的签名是否有效
|
|
|
+ if !isValidSignature(apiKey, signature, timestamp) {
|
|
|
+ err := errors.New("Invalid Signature")
|
|
|
+ data := lib.JSONS{Code: 202, Msg: err.Error()}
|
|
|
+ ctx.Output.JSON(data, true, false)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验时间戳是否在合理范围内(防止重放攻击)
|
|
|
+ sec, _ := strconv.ParseInt(timestamp, 10, 64)
|
|
|
+ reqTime := time.Unix(sec, 0)
|
|
|
+ if time.Since(reqTime) > 5*time.Minute {
|
|
|
+ err := errors.New("Request too old or invalid timestamp")
|
|
|
+ data := lib.JSONS{Code: 202, Msg: err.Error()}
|
|
|
+ ctx.Output.JSON(data, true, false)
|
|
|
+ return
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func init() {
|
|
|
+ //beego.InsertFilter("/openapi", beego.BeforeRouter, ApiKeyAuthMiddleware)
|
|
|
+
|
|
|
+ ns := beego.NewNamespace("/openapi",
|
|
|
+ beego.NSBefore(ApiKeyAuthMiddleware),
|
|
|
+ beego.NSRouter("/user/list", &controllers.AccountController{}, "*:List_All_For_ERP"), // 管理员所有列表
|
|
|
+ )
|
|
|
+ beego.AddNamespace(ns)
|
|
|
+}
|