2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Goの標準ライブラリだけでJWTをデコードしてみたら意外と簡単だったwww

Last updated at Posted at 2023-08-13

はじめに

jwtをデコードしユーザー情報を取得する処理を書く機会があったのですが、Goではサードパーティ製のライブラリを使わずとも意外と簡単に実装できたので、コピペするだけで簡単に使用できるサンプルをここで共有したいと思います。

サンプル

func decode(token string) ([]byte, error) {
	// jwtはピリオド区切りで3つのパーツに分かれている
	// [0]はヘッダー, [1]はペイロード, [2]はシグネチャー
	// 今回必要なユーザー情報などはペイロードに含まれているため[1]を取得している
	splitToken := strings.Split(token, ".")
	if len(splitToken) != 3 {
		panic(err)
	}
	payload := splitToken[1]

	// base64は文字数が4の倍数でないとデコードできないため末尾に"="を挿入することでパディングする
	paddingLength := ((4 - len(payload)%4) % 4)
	padding := strings.Repeat("=", paddingLength)
	paddedPayload := strings.Join([]string{payload, padding}, "")

	// デコード
	decodedPayload, err := base64.StdEncoding.DecodeString(paddedPayload)
	if err != nil {
		panic(err)
	}

	return decodedPayload, nil
}

使用例

以下の内容はginのミドルウェアとして使用する場合の例

type sampleClaim struct {
	ID   string
	name string
	role string
}

func DecodeJwt() gin.HandlerFunc {
	return func(c *gin.Context) {
        // リクエストのヘッダーから認証に関する情報を取得
        // 内容が空白であればエラーを返す
		auth := strings.TrimSpace(c.Request.Header.Get("Authorization"))
		if len(auth) <= 0 {
			// 適当なエラーレスポンスをここに記述
			// 長くなりそうなので省略
		}

        // 先ほど取得した内容からjwtを抜き出し取得する
		token := auth[len("Bearer "):]
		decodedToken, err := decode(token)
		if err != nil {
			// 適当なエラーレスポンスをここに記述
			// 長くなりそうなので省略
		}

        // デコードしたtoken(json)を構造体として定義
		var claims sampleClaim
		if err := json.Unmarshal(decodedToken, &claims); err != nil {
			// 適当なエラーレスポンスをここに記述
			// 長くなりそうなので省略
		}

        // 構造体をcontextに保持させる
		c.Set("claims", claims)
		c.Next()
	}
}

func decode(token string) ([]byte, error) {
	// 省略
	return []byte{}, nil
}

終わりに

今回はjwtが適切かどうかを検証する処理は記述しませんでしたが、それも標準ライブラリのみで簡単に記述できそうでした。気が向いたらそちらも記事にしようかと思います。
お恥ずかしながらjwtの仕組みを知らずに今まで仕事してきたので、個人的にはとても学びのある経験ができました。

もしコードに誤りや非効率な部分がありましたら遠慮なくコメントしていただけると幸いです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?