Maison  >  Article  >  développement back-end  >  Sécuriser votre API Go avec l'authentification JWT

Sécuriser votre API Go avec l'authentification JWT

Susan Sarandon
Susan Sarandonoriginal
2024-10-03 12:07:01728parcourir

Securing Your Go API with JWT Authentication

Très bien, soyons réalistes une seconde. La sécurité est un gros problème, et si vous créez des API, vous ne pouvez pas laisser n'importe qui entrer et commencer à manipuler vos données. C'est là que JWT (JSON Web Tokens) entre en jeu pour sauver la situation. Aujourd'hui, nous améliorons notre API Go en ajoutant une authentification basée sur JWT.

Un avertissement rapide ?

Si vous utilisez l'ancien package github.com/dgrijalva/jwt-go, il est temps de procéder à une mise à niveau. La nouvelle norme est github.com/golang-jwt/jwt/v4.

Pourquoi ce changement ?

  • L'auteur original a passé le relais et les nouveaux responsables ont été occupés à apporter des améliorations et à résoudre les problèmes de sécurité.
  • À partir de la version 4.0.0, ils ont ajouté la prise en charge du module Go et amélioré la validation des jetons.
  • Consultez leur MIGRATION_GUIDE.md si vous utilisez toujours l'ancien package.

Maintenant, commençons avec notre nouvelle bibliothèque JWT sophistiquée !

Qu’est-ce que JWT encore ? ?

Pour ceux qui découvrent JWT :

  • C'est comme un formulaire d'autorisation signé pour accéder à votre API.
  • L'API génère un jeton, le signe et le client (utilisateur, application, etc.) inclut ce jeton dans chaque requête.
  • Le serveur vérifie le jeton et dit : « Ouais, vous êtes légitime. »

Maintenant que vous êtes au courant, passons au code !


Mise en place du projet

Nous reprenons là où nous nous étions arrêtés dans le dernier post. Mettons à jour notre module Go et installons les packages nécessaires :

  1. Ajoutez le package JWT et le routeur multiplex :
   go get github.com/golang-jwt/jwt/v4
   go get github.com/gorilla/mux
  1. Ouvrez votre fichier main.go et passons au codage !

Étape 1 : générer un jeton JWT

Tout d'abord, nous allons créer une fonction qui génère un jeton JWT lorsqu'un utilisateur se connecte. Ce jeton contiendra le nom d'utilisateur et sera signé à l'aide d'une clé secrète.

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
}

Cette fonction génère un token qui expire au bout de 5 minutes, signé à l'aide de l'algorithme HS256.


Étape 2 : Créer le point de terminaison de connexion

Ensuite, nous allons créer un point de terminaison de connexion où les utilisateurs envoient leurs informations d'identification. Si les informations de connexion sont vérifiées, nous générerons un JWT et le renverrons dans un 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),
    })
}

Étape 3 : Middleware pour la validation JWT

Maintenant, nous avons besoin d'une fonction middleware pour valider les jetons JWT avant d'autoriser l'accès aux routes protégées.

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)
    })
}

Ce middleware vérifie si la requête contient un jeton JWT valide. Sinon, il renvoie une réponse non autorisée.


Étape 4 : Protéger les routes

Maintenant, appliquons notre middleware d'authentification pour protéger la route /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))
}

Tester l'API

  1. Connectez-vous pour générer un jeton :
   curl -X POST http://localhost:8000/login -d '{"username":"admin", "password":"password"}' -H "Content-Type: application/json"
  1. Accédez au point de terminaison protégé /books :
   curl --cookie "token=<your_token>" http://localhost:8000/books

Si le jeton est valide, vous aurez accès. Sinon, vous obtiendrez un « 401 non autorisé ».


Quelle est la prochaine étape ?

La prochaine fois, nous connecterons notre API à une base de données pour gérer les informations d'identification des utilisateurs et stocker les données. Restez à l'écoute pour en savoir plus !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn