上京エンジニアの葛藤

都会に染まる日々

golang-jwt/jwt で JWT の発行、検証を行う

golang-jwt/jwt を使って JWT の発行、検証を試したので残しておきます。

github.com

サンプルコードはこちら。

github.com

JWT の発行

func generate() (string, error) {
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{
        Issuer:    "issuer",
        Subject:   "subject",
        Audience:  []string{"audience"},
        ExpiresAt: jwt.NewNumericDate(time.Now().Add(10 + time.Minute)),
        NotBefore: jwt.NewNumericDate(time.Now()),
        IssuedAt:  jwt.NewNumericDate(time.Now()),
        ID:        "id",
    })
    tokenString, err := token.SignedString(secret)
    if err != nil {
        return "", err
    }

    return tokenString, nil
}

JWT の検証

func verify(tokenString string) error {
    token, err := jwt.ParseWithClaims(
        tokenString,
        &jwt.RegisteredClaims{},
        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 secret, nil
        },
    )
    if err != nil {
        return err
    }

    if claims, ok := token.Claims.(*jwt.RegisteredClaims); ok && token.Valid {
        fmt.Println(claims.Issuer)
    } else {
        return err
    }
    return nil
}

Claims の値を検証したいことがあると思いますが、この時 jwt.ParseWithClaims メソッドの引数に ParserOption を渡すことで上手くバリデーションをしてくれるようで使い勝手が良かったです。

例えば、このように sub 値をバリデーションしてくれます。

   token, err := jwt.ParseWithClaims(
        tokenString,
        &jwt.RegisteredClaims{},
        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 secret, nil
        },
        jwt.WithSubject("hoge"),
    )

もちろん sub 値だけではなく、exp, nbf 値なども定義されているメソッドでバリデーションすることができます。

jwt/validator.go at 8b7470d561f313acbf05e17701cbe34ab39fb970 · golang-jwt/jwt · GitHub