MENU

GoでJWTを作ってみた。

自分は認証にJWTをよく使っています。

そのJWTをざっくり理解したいと思い、JWTを作ってみました。

目次

早速作る

package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"strings"
)

var (
	hs256Key    = "secret-key"
	headerJSON  = `{"alg": "HS256", "typ": "JWT"}`
	payloadJSON = `{"iss": "yuyan", "id": "123456"}`
)

func main() {
	// headerをbase64URLでエンコード
	base64Header := base64.RawURLEncoding.EncodeToString([]byte(headerJSON))

	// payloadをbase64URLでエンコードする
	base64Payload := base64.RawURLEncoding.EncodeToString([]byte(payloadJSON))

	// HMAC SHA256で header.payload をハッシュ化
	mac := hmac.New(sha256.New, []byte(hs256Key))
	mac.Write([]byte(fmt.Sprintf("%s.%s", base64Header, base64Payload)))
	// ハッシュ化した値をbase64URLでエンコードする
	base64Signature := base64.RawURLEncoding.EncodeToString((mac.Sum(nil)))
	// base64Signatureから = を取り除く

	// header.payload.signatureでJWTが完成!
	jwt := fmt.Sprintf("%s.%s.%s", base64Header, base64Payload, base64Signature)

	fmt.Println(jwt)
	// eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAieXV5YW4iLCAiaWQiOiAiMTIzNDU2In0.rbpRDicBTBVeqLvTA-Pw1LKZyb7u8Xqid0rgSNGThDY
}

デコードしてみる

func decodeJWT(token string) bool {
	arr := strings.Split(token, ".")
	if len(arr) != 3 {
		fmt.Println("invalid token")
		return false
	}
	header := arr[0]
	payload := arr[1]
	signature := arr[2]

	mac := hmac.New(sha256.New, []byte("secret-key"))
	mac.Write([]byte(fmt.Sprintf("%s.%s", header, payload)))
	verify := base64.RawURLEncoding.EncodeToString(mac.Sum(nil))

	if !hmac.Equal([]byte(signature), []byte(verify)) {
		fmt.Println("invalid hs256key")
		return false
	}
	return true
}

感想

結構お手軽に作成できるんですね。

これだと「絶対にJWTに秘密情報を入れるな!」っていう理由がわかりますね。ペイロードはただbase64でエンコードしているだけなんですね。誰でも中身見放題ですもん。

参考

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

CAPTCHA

目次