openapi.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package routers
  2. import (
  3. "ColdVerify_server/conf"
  4. "ColdVerify_server/controllers"
  5. "ColdVerify_server/lib"
  6. "ColdVerify_server/logs"
  7. "crypto/hmac"
  8. "crypto/sha256"
  9. "encoding/hex"
  10. "errors"
  11. beego "github.com/beego/beego/v2/server/web"
  12. "github.com/beego/beego/v2/server/web/context"
  13. "strconv"
  14. "time"
  15. )
  16. const apiKeyHeader = "X-API-KEY"
  17. const apiSignatureHeader = "X-API-SIGNATURE"
  18. const apiTimestampHeader = "X-API-TIMESTAMP"
  19. func isValidSignature(apiKey, signature, timestamp string) bool {
  20. // 使用提供的 API Key 查找对应的 API Secret
  21. if apiKey != conf.OpenApi_Key {
  22. return false
  23. }
  24. secret := conf.OpenApi_Secret
  25. // 计算签名,签名内容是 "apiKey + timestamp"
  26. message := apiKey + timestamp
  27. mac := hmac.New(sha256.New, []byte(secret))
  28. mac.Write([]byte(message))
  29. expectedSignature := hex.EncodeToString(mac.Sum(nil))
  30. logs.Println("apiKey:", apiKey)
  31. logs.Println("secret:", secret)
  32. logs.Println("时间戳:", timestamp)
  33. logs.Println("生成的签名:", expectedSignature)
  34. logs.Println("传递的签名:", signature)
  35. // 验证客户端提供的签名是否与预期签名匹配
  36. return hmac.Equal([]byte(signature), []byte(expectedSignature))
  37. }
  38. func ApiKeyAuthMiddleware(ctx *context.Context) {
  39. apiKey := ctx.Input.Query(apiKeyHeader)
  40. signature := ctx.Input.Query(apiSignatureHeader)
  41. timestamp := ctx.Input.Query(apiTimestampHeader)
  42. // 检查 API Key, 签名和时间戳是否存在
  43. if apiKey == "" || signature == "" || timestamp == "" {
  44. err := errors.New("API Key, Signature, and Timestamp required")
  45. data := lib.JSONS{Code: 202, Msg: err.Error()}
  46. ctx.Output.JSON(data, true, false)
  47. return
  48. }
  49. // 校验请求的签名是否有效
  50. if !isValidSignature(apiKey, signature, timestamp) {
  51. err := errors.New("Invalid Signature")
  52. data := lib.JSONS{Code: 202, Msg: err.Error()}
  53. ctx.Output.JSON(data, true, false)
  54. return
  55. }
  56. // 校验时间戳是否在合理范围内(防止重放攻击)
  57. sec, _ := strconv.ParseInt(timestamp, 10, 64)
  58. reqTime := time.Unix(sec, 0)
  59. if time.Since(reqTime) > 5*time.Minute {
  60. err := errors.New("Request too old or invalid timestamp")
  61. data := lib.JSONS{Code: 202, Msg: err.Error()}
  62. ctx.Output.JSON(data, true, false)
  63. return
  64. }
  65. }
  66. func init() {
  67. //beego.InsertFilter("/openapi", beego.BeforeRouter, ApiKeyAuthMiddleware)
  68. ns := beego.NewNamespace("/openapi",
  69. beego.NSBefore(ApiKeyAuthMiddleware),
  70. beego.NSRouter("/admin/list", &controllers.AccountController{}, "*:Account_List_All_For_ERP"), // 管理员所有列表
  71. beego.NSRouter("/company/list", &controllers.UserController{}, "*:User_List_All_For_ERP"), // 公司所有列表
  72. beego.NSRouter("/task/list", &controllers.TaskController{}, "*:Task_List_All_For_ERP"), // 公司所有列表
  73. )
  74. beego.AddNamespace(ns)
  75. }