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.
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 ?
Maintenant, commençons avec notre nouvelle bibliothèque JWT sophistiquée !
Pour ceux qui découvrent JWT :
Maintenant que vous êtes au courant, passons au code !
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 :
go get github.com/golang-jwt/jwt/v4 go get github.com/gorilla/mux
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.
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), }) }
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.
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)) }
curl -X POST http://localhost:8000/login -d '{"username":"admin", "password":"password"}' -H "Content-Type: application/json"
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é ».
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!