sign.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package pkg
  2. import (
  3. "bytes"
  4. "crypto/md5"
  5. "encoding/hex"
  6. "fmt"
  7. "net/url"
  8. "sort"
  9. "strings"
  10. "go-common/library/log"
  11. "github.com/google/go-querystring/query"
  12. )
  13. const (
  14. _sign = "sign"
  15. )
  16. // Signer.
  17. type Signer struct {
  18. Key string
  19. }
  20. func (s *Signer) struct2Values(in interface{}) (out url.Values, err error) {
  21. out, err = query.Values(in)
  22. if err != nil {
  23. return
  24. }
  25. out.Del(_sign)
  26. return
  27. }
  28. func (s *Signer) encodeUrlValues(values url.Values) (res string) {
  29. keys := make([]string, 0)
  30. for key := range values {
  31. keys = append(keys, key)
  32. }
  33. sort.Strings(keys)
  34. kvSli := make([]string, 0)
  35. for _, key := range keys {
  36. kvStr := fmt.Sprintf("%s=%s", key, values.Get(key))
  37. kvSli = append(kvSli, kvStr)
  38. }
  39. paramsStr := strings.Join(kvSli, "&")
  40. return strings.ToLower(paramsStr) + "&key=" + s.Key
  41. }
  42. func (s *Signer) escapeStr(str string) (res string) {
  43. return s.adapt(url.QueryEscape(str))
  44. }
  45. func (s *Signer) md5(str string) (res string) {
  46. var (
  47. buf bytes.Buffer
  48. )
  49. buf.WriteString(str)
  50. hexMd5 := md5.Sum(buf.Bytes())
  51. return strings.ToUpper(hex.EncodeToString(hexMd5[:]))
  52. }
  53. // Sign makes sign for yst request.
  54. func (s *Signer) Sign(in interface{}) (sign string, err error) {
  55. var (
  56. values url.Values
  57. )
  58. if values, err = s.struct2Values(in); err != nil {
  59. log.Error("signer.struct2Values(%+v) err(%+v)", in, err)
  60. return
  61. }
  62. encodedVals := s.encodeUrlValues(values)
  63. escapedVals := s.escapeStr(encodedVals)
  64. sign = s.md5(escapedVals)
  65. log.Info("Signer.Sign(%+v) sign(%s)", in, sign)
  66. return
  67. }
  68. // NOTE: 经核对,云视听只有 `*` 不需要转义
  69. func (s *Signer) adapt(str string) string {
  70. res := str
  71. res = strings.Replace(res, "%2A", "*", -1)
  72. return res
  73. }