【问题标题】:JWT Go/Golang base64 encoding payload yields different resultsJWT Go/Golang base64 编码负载产生不同的结果
【发布时间】:2019-09-19 09:03:05
【问题描述】:

我有以下 JWT 有效负载: {"exp": 4724377561}(从现在起 100 年后的某个日期)

在 Go 中编码产生ewogICAiZXhwIjogNDcyNDM3NzU2MQp9 然而,使用jwt.io,它被编码为eyJleHAiOjQ3MjQzNzc1NjF9,在签名时会产生不同的签名。我在测试夹具中使用 jwt.io 的签名。

我不想使用 3rd 方 JWT 工具,以保持我的依赖项很小。 我怀疑某种字符编码是这里的问题。

为了保持测试的可读性,我在夹具中使用纯文本 JSON。

我使用测试夹具的方式如下(省略其他测试用例):

import (
    "encoding/base64"
    "reflect"
    "testing"
)

var testData = []struct {
    name      string
    header    string
    payload   string
    signature string
    pass      bool
    errorType reflect.Type
}{{
    name:      "Succeed if token not expired",
    header:    `{"typ":"JWT","alg":"HS256"}`,
    payload:   `{"exp": 4724377561}`,
    signature: "JHtMKvPSMa5BD22BsbxiP1-ELRh1XkIKkarRSev0ZjU",
    pass:      true,
}}

func TestParseJwt(t *testing.T) {
    HmacSecret = []byte("My super secret key")
    for _, tst := range testData {
        jwt64 :=
            base64.RawURLEncoding.EncodeToString([]byte(tst.header)) + "." +
            base64.RawURLEncoding.EncodeToString([]byte(tst.payload)) + "." +
            tst.signature

        _, err := ParseJwt(jwt64)

        if tst.pass {
            if err != nil {
                t.Fatal(tst.name, err)
            }
        } else {
            // If an error was expected to be thrown, assert that it is the correct one.
            if reflect.TypeOf(err).String() != tst.errorType.String() {
                t.Fatal(tst.name, err)
            }
        }
    }
}

【问题讨论】:

    标签: go base64 jwt base64url


    【解决方案1】:

    区别仅仅在于库在应用 Base64 编码之前“压缩”了 JSON。

    看这个例子:

    ss := []string{
        `{"exp": 4724377561}`,
        `{"exp":4724377561}`,
    }
    for _, s := range ss {
        fmt.Println(base64.RawURLEncoding.EncodeToString([]byte(s)), s)
    }
    

    输出(在Go Playground 上试试):

    eyJleHAiOiA0NzI0Mzc3NTYxfQ {"exp": 4724377561}
    eyJleHAiOjQ3MjQzNzc1NjF9 {"exp":4724377561}
    

    第二个输出符合您的预期。要在 Go 中删除无关紧要的空格,请使用 json.Compact。

    【讨论】:

      【解决方案2】:

      在https://www.base64decode.org/ 上转换回编码字符串告诉你发生了什么:

      ewogICAiZXhwIjogNDcyNDM3NzU2MQp9
      

      被解码为

      {
      "exp": 4724377561
      }
      

      jwt.io 字符串被解码为

      {"exp":4724377561}
      

      所以https://jwt.io 在编码之前修剪所有空格和换行符。

      【讨论】:

        猜你喜欢
        • 2018-09-13
        • 1970-01-01
        • 2019-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-28
        • 2020-09-18
        • 1970-01-01
        相关资源
        最近更新 更多