DarkLogo

GinでJWTを使ったAPI認証

· ChatGPT Turbo

1. 必要なパッケージをインポートする

GinフレームワークとJWTパッケージをインポートします。

import (
	"github.com/gin-gonic/gin"
	"github.com/dgrijalva/jwt-go"
	"time"
	"net/http"
)

2. JWTトークンを生成するハンドラーを実装する

JWTトークンを生成するためのハンドラーを実装します。このハンドラーは、ユーザーIDを受け取り、JWTトークンを生成します。

func generateToken(userID string) (string, error) {
	// トークンの生成
	token := jwt.New(jwt.SigningMethodHS256)

	// トークンにクレームを追加する
	claims := token.Claims.(jwt.MapClaims)
	claims["user_id"] = userID
	claims["exp"] = time.Now().Add(time.Hour * 72).Unix()

	// トークンを署名する
	secret := []byte("secret")
	tokenString, err := token.SignedString(secret)
	if err != nil {
		return "", err
	}

	return tokenString, nil
}

3. JWTトークンを検証するミドルウェアを実装する

JWTトークンを検証するためのミドルウェアを実装します。このミドルウェアは、APIリクエストに含まれているトークンを検証し、トークンが正当である場合にのみAPIリクエストを実行します。

func authenticate() gin.HandlerFunc {
  return func(c *gin.Context) {
    // トークンを取得する
    tokenString := c.GetHeader("Authorization")
    if tokenString == "" {
      c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
        "error": "Authorization header is missing",
      })

      return
    }

    // トークンを検証する
    token, err := jwt.Parse(tokenString, 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("secret"), nil
    })
    if err != nil {
      c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
        "error": "Failed to validate token",
      })

      return
    }

    // トークンが正当である場合、APIリクエストを実行する
    if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
      c.Set("user_id", claims["user_id"])
      c.Next()
    } else {
      c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
        "error": "Token is not valid",
      })
    }
  }
}

4. Ginのエンドポイントとミドルウェアを設定する

GinフレームワークにAPIエンドポイントを追加し、JWT認証ミドルウェアを適用する設定を行います。

func main() {
	r := gin.Default()

	// JWT認証ミドルウェアを追加する
	r.Use(authenticate())

	// APIエンドポイントを追加する
	r.GET("/api", func(c *gin.Context) {
		userID := c.MustGet("user_id").(string)
		c.JSON(200, gin.H{
			"message": "Hello, " + userID,
		})
	})

	r.Run()
}

これで、Ginを使ってJWTを使ったAPI認証が実装できます。実際のアプリケーションでは、トークンの生成と検証に使用するアルゴリズムや署名キーなど、詳細な実装は適宜調整する必要があります。