必要なライブラリ
go get github.com/dgrijalva/jwt-go
色々な動作確認
package main
import (
"fmt"
"time"
"github.com/dgrijalva/jwt-go"
)
func CreateToken(secretKey string) (string, error) {
claims := jwt.MapClaims{}
claims["authorized"] = true
claims["user_id"] = "sample"
claims["exp"] = time.Now().Add(time.Second * 2).Unix() // 有効期限を1時間に設定
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(secretKey))
}
func ValidateToken(tokenString string, secretKey string) (*jwt.Token, error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("予期しない署名方法: %v", token.Header["alg"])
}
return []byte(secretKey), nil
})
if err != nil {
return nil, err
}
return token, nil
}
func IsAuthorized(token *jwt.Token) bool {
if _, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return true
}
return false
}
// falseの場合は期限が切れていない
func IsExpired(token *jwt.Token) bool {
// トークンのクレームをMapClaimsとして取得し、トークンが有効であるか確認
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
// `exp`クレームをUnixタイムスタンプとして取得
if exp, ok := claims["exp"].(float64); ok {
// 現在時刻と比較し、有効期限が切れているか確認
return int64(exp) < time.Now().Unix()
}
}
// 有効期限の情報がない場合は、期限切れとみなす
return true
}
func GetUserID(token *jwt.Token) string {
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims["user_id"].(string)
}
return ""
}
func main() {
secretKey := "abcdesfghijklmnopqrstuvwxyz"
wrongKey := "abcdesfghijklmnopqrstuvwxy"
tokenString, err := CreateToken(secretKey)
if err != nil {
fmt.Println(err)
}
fmt.Println(tokenString)
token, err := ValidateToken(tokenString, secretKey)
if err != nil {
fmt.Println(err)
}
fmt.Println(token)
// secretKeyが違う場合
wrongToken, err := ValidateToken(tokenString, wrongKey)
if err != nil {
fmt.Println(err)
}
fmt.Println(wrongToken)
isAuthorized := IsAuthorized(token)
fmt.Println(isAuthorized)
// 本当はこの処理は不要
isExpired := IsExpired(token)
fmt.Println(isExpired)
// wait 2 seconds
time.Sleep(5 * time.Second)
wrongToken2, err := ValidateToken(tokenString, secretKey)
if err != nil {
fmt.Println("有効期限切れ")
fmt.Println(err)
}
fmt.Println(wrongToken2)
isExpired = IsExpired(token)
fmt.Println(isExpired)
userID := GetUserID(token)
fmt.Println(userID)
}
GolangでJWTをPythonで認証できるかやってみる
JWTの有効期限を1時間に変更する
func CreateToken(secretKey string) (string, error) {
claims := jwt.MapClaims{}
claims["authorized"] = true
claims["user_id"] = "sample"
claims["exp"] = time.Now().Add(time.Hour * 1).Unix() // 有効期限を1時間に設定
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(secretKey))
}
HS256アルゴリズムを使用してJWTトークンを生成しているためPythonのように言語が違ってもトークンとシークレットキーがあればトークンをデコードできます。
import jwt
# トークンをデコードする関数
def decode_token(token, secret_key):
try:
# トークンをデコード
decoded = jwt.decode(token, secret_key, algorithms=["HS256"])
return decoded
except jwt.ExpiredSignatureError:
# トークンの有効期限切れ
return "Expired token."
except jwt.InvalidTokenError:
# トークンが無効
return "Invalid token."
# トークンと秘密鍵
token = "" # ここにGo言語のコードで生成されたトークンを入れる
secret_key = "abcdesfghijklmnopqrstuvwxyz" # ここに秘密鍵を入れる
# トークンをデコード
decoded_token = decode_token(token, secret_key)
print(decoded_token)