BOP的签名
This commit is contained in:
@@ -0,0 +1,84 @@
|
|||||||
|
package bopx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.yun.ink/pkg/convx"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 缺点
|
||||||
|
// 1.值必须是字符串,数组/对象这些不允许,或者需要通过一定规则转成字符串
|
||||||
|
|
||||||
|
type apix struct {
|
||||||
|
ingoreKey []string
|
||||||
|
signKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApi(ignoreKey []string, signKey string) *apix {
|
||||||
|
return &apix{
|
||||||
|
ingoreKey: ignoreKey,
|
||||||
|
signKey: signKey,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 签名规则
|
||||||
|
// 1.除掉不参与签名的用户参数
|
||||||
|
// 1.所有参数的key根据字典排序
|
||||||
|
// 2.根据key=val&key2=val2的格式组装字符串
|
||||||
|
// 3.后面拼接用户签名key `&key=xxxx`得道新字符串
|
||||||
|
// 4.把新字符串用md5加密并转大写的道签名的值
|
||||||
|
func (l *apix) GetSign(params map[string]interface{}) (sign string, err error) {
|
||||||
|
for _, val := range l.ingoreKey {
|
||||||
|
delete(params, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排序
|
||||||
|
keys := make([]string, len(params))
|
||||||
|
i := 0
|
||||||
|
for k := range params {
|
||||||
|
keys[i] = k
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
var str string
|
||||||
|
for k, v := range keys {
|
||||||
|
if k > 0 {
|
||||||
|
str = str + "&"
|
||||||
|
}
|
||||||
|
val, err := convx.ToString(params[v])
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
str = str + v + "=" + val
|
||||||
|
}
|
||||||
|
str = str + "&key=" + l.signKey
|
||||||
|
data := []byte(str)
|
||||||
|
has := md5.Sum(data)
|
||||||
|
md5str1 := fmt.Sprintf("%x", has) // []byte转16进制
|
||||||
|
sign = strings.ToUpper(md5str1)
|
||||||
|
return sign, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *apix) Verify(params map[string]interface{}) error {
|
||||||
|
|
||||||
|
sign, ok := params["sign"]
|
||||||
|
if !ok {
|
||||||
|
return ErrorSignParamNotExist
|
||||||
|
}
|
||||||
|
sitn_str, ok := sign.(string)
|
||||||
|
if !ok {
|
||||||
|
return ErrorSignMustBeString
|
||||||
|
}
|
||||||
|
g_sign, err := l.GetSign(params)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if sitn_str != g_sign {
|
||||||
|
return ErrorSignFail
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package bopx
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrorSignParamNotExist = errors.New("签名参数不存在")
|
||||||
|
ErrorSignMustBeString = errors.New("sign必须是字符串")
|
||||||
|
ErrorSignFail = errors.New("验签失败")
|
||||||
|
)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
module code.yun.ink/pkg/bopx
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
require code.yun.ink/pkg/convx v1.0.1
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
code.yun.ink/pkg/convx v1.0.1 h1:T6yIVqyC1nQc9CO0C7iHn5rs7GxbaulmrJtxwg95q9Y=
|
||||||
|
code.yun.ink/pkg/convx v1.0.1/go.mod h1:6xqmUend1kwarRvJ0TQlfzzS4QCWdRrXQiUY/ggzYqo=
|
||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
// 这个方法适配BOP的签名
|
||||||
|
package bopx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.yun.ink/pkg/convx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type platform struct {
|
||||||
|
ingoreKey []string
|
||||||
|
signKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPlatform(ignoreKey []string, signKey string) *platform {
|
||||||
|
return &platform{
|
||||||
|
ingoreKey: ignoreKey,
|
||||||
|
signKey: signKey,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *platform) GetSign(params map[string]interface{}) (sign string, err error) {
|
||||||
|
for _, val := range l.ingoreKey {
|
||||||
|
delete(params, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排序
|
||||||
|
keys := make([]string, len(params))
|
||||||
|
i := 0
|
||||||
|
for k := range params {
|
||||||
|
keys[i] = k
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
var str string
|
||||||
|
for k, v := range keys {
|
||||||
|
if k > 0 {
|
||||||
|
str = str + "&"
|
||||||
|
}
|
||||||
|
val, err := convx.ToString(params[v])
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
str = str + v + "=" + val
|
||||||
|
}
|
||||||
|
str = str + "&key=" + l.signKey
|
||||||
|
data := []byte(str)
|
||||||
|
has := md5.Sum(data)
|
||||||
|
md5str1 := fmt.Sprintf("%x", has) // []byte转16进制
|
||||||
|
sign = strings.ToUpper(md5str1)
|
||||||
|
return sign, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *platform) VerifySign(params map[string]interface{}) error {
|
||||||
|
sign, ok := params["sign"]
|
||||||
|
if !ok {
|
||||||
|
return ErrorSignParamNotExist
|
||||||
|
}
|
||||||
|
sitn_str, ok := sign.(string)
|
||||||
|
if !ok {
|
||||||
|
return ErrorSignMustBeString
|
||||||
|
}
|
||||||
|
g_sign, err := l.GetSign(params)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if sitn_str != g_sign {
|
||||||
|
return ErrorSignFail
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package bopx_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.yun.ink/pkg/bopx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetSign(t *testing.T) {
|
||||||
|
params := map[string]interface{}{
|
||||||
|
"name": "huang",
|
||||||
|
"age": 18,
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete(params, "platform_key")
|
||||||
|
// delete(params, "sign")
|
||||||
|
// delete(params, "key")
|
||||||
|
|
||||||
|
s := bopx.NewPlatform([]string{"platform_key", "sign", "key"}, "huangxinyun")
|
||||||
|
sign, err := s.GetSign(params)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
t.Log(sign)
|
||||||
|
params["sign"] = sign
|
||||||
|
err = s.VerifySign(params)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user