ホームページ >バックエンド開発 >Golang >JWT 認証による Go API の保護

JWT 認証による Go API の保護

Susan Sarandon
Susan Sarandonオリジナル
2024-10-03 12:07:01846ブラウズ

Securing Your Go API with JWT Authentication

それでは、少し本題に移りましょう。セキュリティは重要な問題であり、API を構築している場合、誰かが勝手に侵入してデータをいじり始めることはできません。そこで窮地を救うためにJWT (JSON Web Tokens) が登場します。現在、JWT ベースの認証を追加して Go API をレベルアップしています。

簡単な注意事項 ?

古い github.com/dgrijalva/jwt-go パッケージを使用している場合は、アップグレードの時期が来ました。新しい標準は github.com/golang-jwt/jwt/v4 です。

なぜ切り替えたのですか?

  • 元の作成者が主導権を引き継ぎ、新しいメンテナは改良とセキュリティ問題の修正に忙しく取り組んでいます。
  • バージョン 4.0.0 から、Go モジュールのサポートが追加され、トークン検証が改善されました。
  • 古いパッケージをまだ使用している場合は、MIGRATION_GUIDE.md を確認してください。

さあ、素晴らしい新しい JWT ライブラリを始めましょう!

もう一度 JWT とは何ですか? ?

JWT を初めて使用する方へ:

  • これは、API にアクセスするための署名済みの許可票のようなものです。
  • API はトークンを生成して署名し、クライアント (ユーザー、アプリなど) はそのトークンをすべてのリクエストに含めます。
  • サーバーはトークンをチェックし、「はい、あなたは正当です。」

理解できたので、コードを詳しく見ていきましょう!


プロジェクトのセットアップ

前回の投稿で中断したところから続けていきます。 Go モジュールを更新し、必要なパッケージをインストールしましょう:

  1. JWT パッケージと多重ルーターを追加します。
   go get github.com/golang-jwt/jwt/v4
   go get github.com/gorilla/mux
  1. main.go ファイルを開いてコーディングを始めましょう!

ステップ 1: JWT トークンを生成する

まず、ユーザーのログイン時に JWT トークンを生成する関数を作成します。このトークンにはユーザー名が含まれ、秘密鍵を使用して署名されます。

var jwtKey = []byte("my_secret_key")

type Credentials struct {
    Username string `json:"username"`
    Password string `json:"password"`
}

type Claims struct {
    Username string `json:"username"`
    jwt.RegisteredClaims
}

func generateToken(username string) (string, error) {
    expirationTime := time.Now().Add(5 * time.Minute)

    claims := &Claims{
        Username: username,
        RegisteredClaims: jwt.RegisteredClaims{
            ExpiresAt: jwt.NewNumericDate(expirationTime),
        },
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    tokenString, err := token.SignedString(jwtKey)
    return tokenString, err
}

この関数は、HS256 アルゴリズムを使用して署名された、5 分後に期限切れになるトークンを生成します。


ステップ 2: ログインエンドポイントを作成する

次に、ユーザーが認証情報を送信するログイン エンドポイントを構築します。ログイン情報がチェックアウトされたら、JWT を生成し、Cookie で送り返します。

func login(w http.ResponseWriter, r *http.Request) {
    var creds Credentials
    err := json.NewDecoder(r.Body).Decode(&creds)
    if err != nil {
        w.WriteHeader(http.StatusBadRequest)
        return
    }

    if creds.Username != "admin" || creds.Password != "password" {
        w.WriteHeader(http.StatusUnauthorized)
        return
    }

    token, err := generateToken(creds.Username)
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    http.SetCookie(w, &http.Cookie{
        Name:    "token",
        Value:   token,
        Expires: time.Now().Add(5 * time.Minute),
    })
}

ステップ 3: JWT 検証用のミドルウェア

ここで、保護されたルートへのアクセスを許可する前に JWT トークンを検証するミドルウェア関数が必要です。

func authenticate(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        c, err := r.Cookie("token")
        if err != nil {
            if err == http.ErrNoCookie {
                w.WriteHeader(http.StatusUnauthorized)
                return
            }
            w.WriteHeader(http.StatusBadRequest)
            return
        }

        tokenStr := c.Value
        claims := &Claims{}

        tkn, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
            return jwtKey, nil
        })

        if err != nil || !tkn.Valid {
            w.WriteHeader(http.StatusUnauthorized)
            return
        }

        next.ServeHTTP(w, r)
    })
}

このミドルウェアは、リクエストに有効な JWT トークンがあるかどうかを確認します。そうでない場合は、不正な応答が返されます。


ステップ 4: ルートの保護

次に、認証ミドルウェアを適用して /books ルートを保護しましょう:

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/login", login).Methods("POST")
    r.Handle("/books", authenticate(http.HandlerFunc(getBooks))).Methods("GET")

    fmt.Println("Server started on port :8000")
    log.Fatal(http.ListenAndServe(":8000", r))
}

API のテスト

  1. ログインしてトークンを生成します:
   curl -X POST http://localhost:8000/login -d '{"username":"admin", "password":"password"}' -H "Content-Type: application/json"
  1. 保護された /books エンドポイントにアクセスします:
   curl --cookie "token=<your_token>" http://localhost:8000/books

トークンが有効であれば、アクセスできます。そうでない場合は、「401 Unauthorized」が表示されます。


次は何ですか?

次回は、API をデータベースに接続して、ユーザーの資格情報を管理し、データを保存します。続報をお楽しみに!

以上がJWT 認証による Go API の保護の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。