我无法将JWT有效负载转换回golang中的结构
我有两个相互通信的服务器,并具有JWT身份验证以加强安全性。
有效负载使用以下结构
type ResponseBody struct {
Header dto.MessageHeader `json:"message_header"`
OrderBodyParams dto.OrderBodyParams `json:"order_response"`
Status string `json:"status"`
ErrorMessage string `json:"errors"`
}
服务器A采用此结构-将其转换为字节日期并将其作为JWT有效负载发送
相关代码在下面
func request(secretKey string, path string, method string, requestParams interface{}, response interface{}) error {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{
Timeout: time.Second * 15,
Transport: tr,
}
//convert body into byte data
requestBody, err := json.Marshal(requestParams)
if err != nil {
return err
}
tokenString, expirationTime, err := authentication.GenerateJWTAuthToken(secretKey, requestBody)
if err != nil {
return err
}
req, _ := http.NewRequest(method, path, bytes.NewBuffer([]byte(tokenString)))
req.Header.Set("Content-Type", "application/json")
req.AddCookie(&http.Cookie{
Name: "token",
Value: tokenString,
Expires: expirationTime,
})
_, err = client.Do(req)
if err != nil {
return err
}
return nil
}
如您所见,我只是将主体转换为字节数据-并将其转换为JWT有效负载
GenerateJWTAuthToken函数如下所示
type Claims struct {
Payload []byte `json:"payload"`
jwt.StandardClaims
}
func GenerateJWTAuthToken(secretKey string, payload []byte) (string, time.Time, error) {
var jwtKey = []byte(secretKey)
// Set expiration to 5 minutes from now (Maybe lesser?)
expirationTime := time.Now().Add(5 * time.Minute)
// create the payload
claims := &Claims{
Payload: payload,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString(jwtKey)
if err != nil {
return "", time.Time{}, fmt.Errorf("Error generating JWT token : %+v", err)
}
return tokenString, expirationTime, nil
}
现在server B
-接收数据并验证JWT,并将字节有效载荷转换回ResponseBody
结构
func Postback(appState *appsetup.AppState) http.HandlerFunc {
fn := func(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
tokenString := string(body)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
// Verify the JWT token send from server A and ensure its a valid request
// If the token is invalid , dont proceed further
token, payload, err := authentication.VerifyJWTToken(appState.SecretKey, tokenString)
if err != nil {
if err == jwt.ErrSignatureInvalid {
w.WriteHeader(http.StatusUnauthorized)
return
}
w.WriteHeader(http.StatusBadRequest)
return
}
if !token.Valid {
w.WriteHeader(http.StatusUnauthorized)
return
}
requestData := ResponseBody{}
err = binary.Read(bytes.NewReader(payload), binary.LittleEndian, &requestData)
if err != nil {
fmt.Printf("Couldnt convert payload body to struct : %+v ", err)
return
}
return requestData
}
return http.HandlerFunc(fn)
}
VerifyJWTToken
函数也非常简单(我希望如此)
func VerifyJWTToken(secretKey string, tokenString string) (*jwt.Token, []byte, error) {
var jwtKey = []byte(secretKey)
var payload []byte
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return jwtKey, nil
})
if err != nil {
return nil, payload, err
}
return token, claims.Payload, nil
}
但是我无法将payload
转换回ResponseBody
结构-
在err = binary.Read(bytes.NewReader(bodyBuffer), binary.LittleEndian, &requestData)
行似乎失败了
出现以下错误
msg":"Couldnt convert payload body to struct : binary.Read: invalid type *ResponseBody "
我有什么想念的吗?
答案 0 :(得分:0)
您正在使用JSON封送您的结构:
requestBody, err := json.Marshal(requestParams)`
因此,您应该使用JSON解封来获取结构。但是,您正在使用binary.Read()
来阅读它:
err = binary.Read(bytes.NewReader(payload), binary.LittleEndian, &requestData)
而是这样做:
err = json.Unmarshal(payload, &requestData)