Honnêtement, il existe de nombreuses méthodes et techniques d'authentification que vous pouvez monter dans votre application et qui dépendent de la logique et des exigences métier des applications.
Par exemple Oauth2, LDAP, authentification locale, etc.
Ma réponse suppose que vous recherchez une authentification locale, ce qui signifie que vous gérez les identités de l'utilisateur dans votre application. Le serveur doit exposer un ensemble d'API externes permettant aux utilisateurs et aux administrateurs de gérer les comptes et la manière dont ils souhaitent s'identifier auprès du serveur pour établir une communication fiable. vous finirez par créer une table DB contenant les informations de l'utilisateur. où le mot de passe est haché à des fins de sécurité Voir Comment stocker le mot de passe dans la base de données
laissez supposer les exigences de l'application pour authentifier les utilisateurs en fonction de l'une des méthodes suivantes:
authentification de base (nom d'utilisateur, mot de passe):
cette méthode d'authentification dépend des ensembles d'informations d'identification de l'utilisateur dans l'en-tête d'autorisation codé en base64 et défini dans rfc7617 , essentiellement lorsque l'application reçoit, l'utilisateur demande son décode l'autorisation et le hachage du mot de passe pour le comparer dans DB hachage s'il correspond à l'utilisateur authentifié, sinon renvoie le code d'état 401 à l'utilisateur.
authentification basée
sur un certificat : cette méthode d'authentification dépend d'un certificat numérique pour identifier un utilisateur, et elle est connue sous le nom d'authentification x509.Ainsi, lorsque l'application reçoit les demandes de l'utilisateur, elle lit le certificat du client et vérifie qu'il correspond au certificat racine de l'autorité de certification fourni à l'APP.
jeton de support:
cette méthode d'authentification dépend de jetons d'accès de courte durée. Le jeton de support est une chaîne cryptique, généralement générée par le serveur en réponse à une demande de connexion. Ainsi, lorsque l'application reçoit les demandes de l'utilisateur, elle lit l'autorisation et valide le jeton pour authentifier l'utilisateur.
Cependant, je recommanderais go-guardian
pour la bibliothèque d'authentification, ce qu'il fait via un ensemble extensible de méthodes d'authentification appelées stratégies. Fondamentalement, Go-Guardian ne monte pas de routes ou n'assume aucun schéma de base de données particulier, ce qui maximise la flexibilité et permet au développeur de prendre des décisions.
La configuration d'un authentificateur go-guardian est simple.
Voici l'exemple complet des méthodes ci-dessus.
package main
import (
"context"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"log"
"net/http"
"sync"
"github.com/golang/groupcache/lru"
"github.com/gorilla/mux"
"github.com/shaj13/go-guardian/auth"
"github.com/shaj13/go-guardian/auth/strategies/basic"
"github.com/shaj13/go-guardian/auth/strategies/bearer"
gx509 "github.com/shaj13/go-guardian/auth/strategies/x509"
"github.com/shaj13/go-guardian/store"
)
var authenticator auth.Authenticator
var cache store.Cache
func middleware(next http.Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Executing Auth Middleware")
user, err := authenticator.Authenticate(r)
if err != nil {
code := http.StatusUnauthorized
http.Error(w, http.StatusText(code), code)
return
}
log.Printf("User %s Authenticated\n", user.UserName())
next.ServeHTTP(w, r)
})
}
func Resource(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Resource!!\n"))
}
func Login(w http.ResponseWriter, r *http.Request) {
token := "90d64460d14870c08c81352a05dedd3465940a7"
user := auth.NewDefaultUser("admin", "1", nil, nil)
cache.Store(token, user, r)
body := fmt.Sprintf("token: %s \n", token)
w.Write([]byte(body))
}
func main() {
opts := x509.VerifyOptions{}
opts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
opts.Roots = x509.NewCertPool()
opts.Roots.AddCert(readCertificate("<root-ca>"))
cache = &store.LRU{
lru.New(100),
&sync.Mutex{},
}
x509Strategy := gx509.New(opts)
basicStrategy := basic.New(validateUser, cache)
tokenStrategy := bearer.New(bearer.NoOpAuthenticate, cache)
authenticator = auth.New()
authenticator.EnableStrategy(gx509.StrategyKey, x509Strategy)
authenticator.EnableStrategy(basic.StrategyKey, basicStrategy)
authenticator.EnableStrategy(bearer.CachedStrategyKey, tokenStrategy)
r := mux.NewRouter()
r.HandleFunc("/resource", middleware(http.HandlerFunc(Resource)))
r.HandleFunc("/login", middleware(http.HandlerFunc(Login)))
log.Fatal(http.ListenAndServeTLS(":8080", "<server-cert>", "<server-key>", r))
}
func validateUser(ctx context.Context, r *http.Request, userName, password string) (auth.Info, error) {
if userName == "stackoverflow" && password == "stackoverflow" {
return auth.NewDefaultUser("stackoverflow", "10", nil, nil), nil
}
return nil, fmt.Errorf("Invalid credentials")
}
func readCertificate(file string) *x509.Certificate {
data, err := ioutil.ReadFile(file)
if err != nil {
log.Fatalf("error reading %s: %v", file, err)
}
p, _ := pem.Decode(data)
cert, err := x509.ParseCertificate(p.Bytes)
if err != nil {
log.Fatalf("error parseing certificate %s: %v", file, err)
}
return cert
}
Usage:
curl -k https://127.0.0.1:8080/login -u stackoverflow:stackoverflow
token: 90d64460d14870c08c81352a05dedd3465940a7
- Authentifiez-vous avec un jeton:
curl -k https://127.0.0.1:8080/resource -H "Authorization: Bearer 90d64460d14870c08c81352a05dedd3465940a7"
Resource!!
- Authentifiez-vous avec un identifiant utilisateur:
curl -k https://127.0.0.1:8080/resource -u stackoverflow:stackoverflow
Resource!!
- Authentifiez-vous avec un certificat utilisateur:
curl --cert client.pem --key client-key.pem --cacert ca.pem https://127.0.0.1:8080/resource
Resource!!
Vous pouvez activer plusieurs méthodes d'authentification à la fois. Vous devez généralement utiliser au moins deux méthodes