-
Notifications
You must be signed in to change notification settings - Fork 15
/
2design.go
148 lines (129 loc) · 3.18 KB
/
2design.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package design
import (
"crypto/md5"
"encoding/base64"
"encoding/json"
"fmt"
"strings"
)
type Header struct {
AppId string
Sign string
}
type Data struct {
Header Header
Body string
}
type AuthToken struct {
sign string
}
func CreateAuthToken() *AuthToken {
return &AuthToken{}
}
func (authToken *AuthToken) Create(appId string, appKey string, body string) string {
h := md5.New()
h.Write([]byte(appId + body + appKey))
authToken.sign = strings.ToUpper(fmt.Sprintf("%x", h.Sum(nil)))
return authToken.sign
}
func (authToken *AuthToken) Match(token *AuthToken) bool {
if authToken.sign == token.sign {
return true
}
return false
}
type ApiRequest struct {
appId string
sign string
data *Data
}
func CreateApiRequest() *ApiRequest {
return &ApiRequest{}
}
func (apiRequest *ApiRequest) Encode(data string) string {
return base64.StdEncoding.EncodeToString([]byte(data))
}
func (apiRequest *ApiRequest) Decode(data string) (appId string, sign string, err error) {
bytes, err := base64.StdEncoding.DecodeString(data)
if err != nil {
return
}
apiRequest.data = &Data{}
if err := json.Unmarshal(bytes, apiRequest.data); err != nil {
return "", "", err
}
apiRequest.appId = apiRequest.data.Header.AppId
apiRequest.sign = apiRequest.data.Header.Sign
return apiRequest.appId, apiRequest.sign, nil
}
func (apiRequest *ApiRequest) GetAppid() string {
return apiRequest.appId
}
func (apiRequest *ApiRequest) GetSign() string {
return apiRequest.sign
}
type CredentialStorage interface {
GetAppkeyByAppid(appId string) string
}
type CredentialStorageConfig struct {
}
func (config *CredentialStorageConfig) GetAppkeyByAppid(appId string) string {
if appId == "test" {
return "test"
}
return "test"
}
type ApiAuthencator struct {
credentialStorage CredentialStorage
}
func CreateApiAuthenCator(cs CredentialStorage) *ApiAuthencator {
return &ApiAuthencator{credentialStorage: cs}
}
func (apiAuthencator *ApiAuthencator) Auth(data string) (bool, error) {
//1.解析数据
apiRequest := CreateApiRequest()
appId, sign, err := apiRequest.Decode(data)
//fmt.Println(appId, sign, apiRequest.data)
if err != nil {
return false, fmt.Errorf("Decode failed")
}
//2.获取appId对应的appkey
appKey := apiAuthencator.credentialStorage.GetAppkeyByAppid(appId)
//3.重新计算sign
authToken := CreateAuthToken()
newSign := authToken.Create(appId, appKey, apiRequest.data.Body)
if sign == newSign {
return true, nil
}
return false, nil
}
func maindesign() {
//客户端
appId := "test"
appKey := "test"
sendData := &Data{
Header: Header{
AppId: appId,
},
Body: "for test",
}
authToken := CreateAuthToken()
sign := authToken.Create(appId, appKey, sendData.Body)
sendData.Header.Sign = sign
sendDataMarshal, _ := json.Marshal(sendData)
sendDataString := CreateApiRequest().Encode(string(sendDataMarshal))
//fmt.Println(sign, sendData, string(sendDataMarshal), string(sendDataString))
//服务端
apiAuthenCator := CreateApiAuthenCator(new(CredentialStorageConfig))
auth, err := apiAuthenCator.Auth(sendDataString)
if err != nil {
fmt.Println(err.Error())
return
}
if auth == false {
fmt.Println("auth failed")
return
}
fmt.Println("auth success")
return
}