📝
【Go】JWTのペイロードから値を簡単に取り出す方法
はじめに
現在個人制作しているWebアプリケーションで、JWTのペイロードにあるidを取り出し認可チェックする実装をしました。
その中で、簡単にペイロードから値を簡単に取り出す方法を知ったので、備忘録的に書いていきます!
環境
- go version go1.24.0 darwin/arm64
結論
JWTのクレームを取得し、jwt.MapClaims型に型アサーションする!
実装
main.go
package main
import (
"fmt"
"log"
"net/http"
"github.com/golang-jwt/jwt/v5"
)
func handler(w http.ResponseWriter, r *http.Request) {
secretKey := "example-secret-key"
// テスト用JWTを生成
testJwt, err := generateJWT(secretKey)
if err != nil {
return
}
// アルゴリズムと署名検証
parsedToken, err := jwt.Parse(testJwt, 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 []byte(secretKey), nil
})
if err != nil || !parsedToken.Valid {
return
}
claims, ok := parsedToken.Claims.(jwt.MapClaims)
if !ok {
return
}
user_id, ok := claims["user_id"].(string)
if !ok {
return
}
fmt.Println(user_id)
// 出力結果:123
}
// テスト用のJWTを生成
func generateJWT(secretKey string) (string, error) {
jwt := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"user_id": "123",
})
signedJWT, _ := jwt.SignedString([]byte(secretKey))
return signedJWT, nil
}
func main() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
parsedToken.Claimsとは
パースしたトークンオブジェクトに格納されているクレーム(ペイロードに格納されている情報)です。
Claimsはjwt.Claimsインターフェース型
で、実際にどんなデータが入っているかはわかりません。
このため、クレームの内容に応じて型を特定する必要があります。
jwt.MapClaimsとは
jwt.MapClaimsは、jwt.MapClaims型で、map[string]interface{}を指します。
型アサーションを行い、jwt.Claimsインターフェース型
を jwt.MapClaims型
に変換します。
キーをしているすることで値を取得することができます。
main.go
claims, ok := parsedToken.Claims.(jwt.MapClaims)
if !ok {
return
}
user_id, ok := claims["user_id"].(string)
if !ok {
return
}
まとめ
JWTのクレームを取得し、jwt.MapClaims型に型アサーションすることで、簡単に値を取り出すことができました!
最初はBase64URLエンコードされているものをデコードしていましたが、こちらの方がより簡単かつ安全に実装できているように感じます。
Discussion