slogan3

Help me bij het implementeren van OAuth2 authenticatie in mijn Go applicatie

description

Het gebruik van OAuth2 verbetert de beveiliging van je applicatie door gebruikersauthenticatie en autorisatie effectief te beheren, wat zorgt voor veiligere interacties met externe diensten.

prompt

try_prompt

Help me OAuth2 authenticatie op te zetten in mijn Go applicatie. Leg uit hoe je de OAuth2 provider configureert, tokens genereert en valideert ... more
generate_helper
disclaimerOnPageApi image_legal_disclaimer...

ai_answers

provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een stapsgewijze handleiding om OAuth2-authenticatie met Google in je Go-applicatie op te zetten, inclusief voorbeeldcode. --- ### 1. OAuth2 Provider configureren (Google) #### a. Google API Console setup 1. Ga naar [Google Cloud Console](https://console.developers.google.com/). 2. Maak een nieuw project of selecteer een bestaand project. 3. Ga naar **Credentials**. 4. Klik op **Create Credentials** > **OAuth 2.0 Client IDs**. 5. Kies **Application Type**: bijvoorbeeld **Web application**. 6. Voeg de **Authorized redirect URIs** toe (bijvoorbeeld: `http://localhost:8080/auth/callback`). 7. Download de `client_secret.json` of noteer de client ID en secret. --- ### 2. OAuth2 in Go integreren Gebruik de officiële `golang.org/x/oauth2` package en de Google provider. #### a. Dependencies installeren ```bash go get golang.org/x/oauth2 go get golang.org/x/oauth2/google ``` #### b. OAuth2 configuratie code voorbeeld ```go package main import ( "context" "fmt" "log" "net/http" "golang.org/x/oauth2" "golang.org/x/oauth2/google" ) var ( // Vervang deze waarden door jouw client ID en secret oauth2Config = &oauth2.Config{ ClientID: "JOUW_CLIENT_ID", ClientSecret: "JOUW_CLIENT_SECRET", RedirectURL: "http://localhost:8080/auth/callback", Scopes: []string{"openid", "profile", "email"}, Endpoint: google.Endpoint, } // In-memory sessies (voor demo), gebruik een database in productie stateToken = "randomstate" // genereer een veilige unieke waarde ) func main() { http.HandleFunc("/", handleMain) http.HandleFunc("/login", handleLogin) http.HandleFunc("/auth/callback", handleCallback) fmt.Println("Server gestart op http://localhost:8080") log.Fatal(http.ListenAndServe(":8080", nil)) } func handleMain(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, `<a href="/login">Login met Google</a>`) } func handleLogin(w http.ResponseWriter, r *http.Request) { url := oauth2Config.AuthCodeURL(stateToken, oauth2.AccessTypeOffline) http.Redirect(w, r, url, http.StatusTemporaryRedirect) } func handleCallback(w http.ResponseWriter, r *http.Request) { if r.FormValue("state") != stateToken { http.Error(w, "Ongeldige state parameter", http.StatusBadRequest) return } code := r.FormValue("code") token, err := oauth2Config.Exchange(context.Background(), code) if err != nil { http.Error(w, "Token verwerving mislukt", http.StatusInternalServerError) return } // Token opslaan en gebruiker authentiseren client := oauth2Config.Client(context.Background(), token) // Haal gebruikersinfo op resp, err := client.Get("https://www.googleapis.com/oauth2/v3/userinfo") if err != nil { http.Error(w, "Fout bij ophalen gebruikersinfo", http.StatusInternalServerError) return } defer resp.Body.Close() // Lees en toon gebruikersinfo // Hier kun je JSON decoderen en gebruiken var userInfo map[string]interface{} if err := json.NewDecoder(resp.Body).Decode(&userInfo); err != nil { http.Error(w, "Fout bij decoderen gebruikersinfo", http.StatusInternalServerError) return } fmt.Fprintf(w, "Gebruiker info: %+v", userInfo) } ``` --- ### 3. Tokens genereren en valideren - **Tokens genereren:** gebeurt automatisch bij `oauth2Config.Exchange()`. - **Tokens valideren:** bevestig dat de access token geldig is door API-aanroepen te doen met de token. Google biedt ook ID tokens (JWT) die je kunt verifieren met de publieke keys van Google. Voor eenvoudige verificatie kun je het access token gebruiken zoals in het voorbeeld. Voor meer veiligheid, valideer de ID token (JWT) met de juiste libraries. --- ### 4. Eindpunten beveiligen - Controleer of de gebruiker ingelogd is voordat je bepaalde routes toelaat. - Bewaar de tokens in sessies of cookies. - Bij elke beveiligde route, check of de gebruiker een geldig token heeft. Voorbeeld: ```go func authMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Hier haal je token uit sessie/cookie // en valideer je deze // Als niet geldig: redirect naar login // Voor demo: ga door next.ServeHTTP(w, r) }) } ``` --- ### Samenvatting - Configureer Google OAuth2 credentials. - Implementeer login en callback endpoints. - Gebruik `oauth2.Config` voor tokenaanvragen. - Haal gebruikersinfo op met de access token. - Beveilig je endpoints door authenticatie te controleren. --- Wil je dat ik je help met een complete, werkende demo of meer details over tokenverificatie en sessiebeheer?
provider: deepseek
model: deepseek-chat
Ik help je graag met het opzetten van OAuth2 authenticatie met Google in je Go applicatie. Hier is een complete uitleg met voorbeeldcode. ## 1. Vereisten en installatie Installeer eerst de benodigde packages: ```bash go get golang.org/x/oauth2 go get golang.org/x/oauth2/google ``` ## 2. OAuth2 configuratie ```go package main import ( "context" "encoding/json" "fmt" "log" "net/http" "golang.org/x/oauth2" "golang.org/x/oauth2/google" ) // OAuth2 configuratie voor Google var googleOauthConfig = &oauth2.Config{ RedirectURL: "http://localhost:8080/auth/google/callback", ClientID: "je-google-client-id", ClientSecret: "je-google-client-secret", Scopes: []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"}, Endpoint: google.Endpoint, } // Willekeurige staat voor beveiliging (in productie gebruik een cryptografisch veilige waarde) var oauthStateString = "random-state-string" ``` ## 3. Google OAuth2 instellen 1. Ga naar [Google Cloud Console](https://console.cloud.google.com/) 2. Maak een nieuw project of selecteer een bestaand project 3. Ga naar "APIs & Services" > "Credentials" 4. Maak een OAuth 2.0 Client ID aan 5. Configureer geautoriseerde redirect URIs (bijv. `http://localhost:8080/auth/google/callback`) ## 4. Authenticatie endpoints ```go // Start OAuth2 flow func handleGoogleLogin(w http.ResponseWriter, r *http.Request) { url := googleOauthConfig.AuthCodeURL(oauthStateString) http.Redirect(w, r, url, http.StatusTemporaryRedirect) } // Callback handler voor Google OAuth2 func handleGoogleCallback(w http.ResponseWriter, r *http.Request) { state := r.FormValue("state") if state != oauthStateString { http.Error(w, "Ongeldige staat parameter", http.StatusBadRequest) return } code := r.FormValue("code") token, err := googleOauthConfig.Exchange(context.Background(), code) if err != nil { http.Error(w, "Kon token niet uitwisselen: "+err.Error(), http.StatusInternalServerError) return } // Valideer token en haal gebruikersinformatie op userInfo, err := getUserInfo(token) if err != nil { http.Error(w, "Kon gebruikersinformatie niet ophalen: "+err.Error(), http.StatusInternalServerError) return } // Sla token op (in productie gebruik een veilige opslag) // Bijvoorbeeld in een cookie of session http.SetCookie(w, &http.Cookie{ Name: "oauth_token", Value: token.AccessToken, Path: "/", HttpOnly: true, Secure: false, // Zet op true in productie met HTTPS }) fmt.Fprintf(w, "Ingelogd als: %s", userInfo.Email) } // Haal gebruikersinformatie op van Google func getUserInfo(token *oauth2.Token) (*GoogleUserInfo, error) { client := googleOauthConfig.Client(context.Background(), token) resp, err := client.Get("https://www.googleapis.com/oauth2/v2/userinfo") if err != nil { return nil, err } defer resp.Body.Close() var userInfo GoogleUserInfo err = json.NewDecoder(resp.Body).Decode(&userInfo) if err != nil { return nil, err } return &userInfo, nil } // Google gebruikersinformatie struct type GoogleUserInfo struct { ID string `json:"id"` Email string `json:"email"` Name string `json:"name"` Picture string `json:"picture"` } ``` ## 5. Token validatie middleware ```go // Middleware om endpoints te beveiligen func authMiddleware(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // Haal token op uit cookie cookie, err := r.Cookie("oauth_token") if err != nil { http.Redirect(w, r, "/login", http.StatusSeeOther) return } // Valideer token (eenvoudige validatie - in productie uitgebreider) token := &oauth2.Token{AccessToken: cookie.Value} client := googleOauthConfig.Client(context.Background(), token) // Test of token nog geldig is door een eenvoudige API call resp, err := client.Get("https://www.googleapis.com/oauth2/v2/userinfo") if err != nil || resp.StatusCode != http.StatusOK { // Token is ongeldig, redirect naar login http.Redirect(w, r, "/login", http.StatusSeeOther) return } resp.Body.Close() // Token is geldig, ga door naar volgende handler next.ServeHTTP(w, r) } } // Uitgebreide token validatie functie func validateToken(accessToken string) (bool, *GoogleUserInfo, error) { token := &oauth2.Token{AccessToken: accessToken} client := googleOauthConfig.Client(context.Background(), token) resp, err := client.Get("https://www.googleapis.com/oauth2/v2/userinfo") if err != nil { return false, nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return false, nil, nil } var userInfo GoogleUserInfo err = json.NewDecoder(resp.Body).Decode(&userInfo) if err != nil { return false, nil, err } return true, &userInfo, nil } ``` ## 6. Complete applicatie integratie ```go package main import ( "fmt" "log" "net/http" "os" ) func main() { // Haal credentials op uit environment variables (veiliger) googleOauthConfig.ClientID = os.Getenv("GOOGLE_CLIENT_ID") googleOauthConfig.ClientSecret = os.Getenv("GOOGLE_CLIENT_SECRET") if googleOauthConfig.ClientID == "" || googleOauthConfig.ClientSecret == "" { log.Fatal("GOOGLE_CLIENT_ID en GOOGLE_CLIENT_SECRET moeten zijn ingesteld") } // Routes http.HandleFunc("/", homeHandler) http.HandleFunc("/login", handleGoogleLogin) http.HandleFunc("/auth/google/callback", handleGoogleCallback) http.HandleFunc("/protected", authMiddleware(protectedHandler)) http.HandleFunc("/logout", logoutHandler) fmt.Println("Server draait op http://localhost:8080") log.Fatal(http.ListenAndServe(":8080", nil)) } func homeHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, ` <h1>Welkom bij de OAuth2 Demo</h1> <a href="/login">Inloggen met Google</a> `) } func protectedHandler(w http.ResponseWriter, r *http.Request) { // Haal gebruikersinformatie op voor weergave cookie, _ := r.Cookie("oauth_token") isValid, userInfo, _ := validateToken(cookie.Value) if isValid && userInfo != nil { fmt.Fprintf(w, ` <h1>Beveiligd gebied</h1> <p>Welkom, %s!</p> <p>Email: %s</p> <img src="%s" alt="Profiel foto" width="50"> <br><br> <a href="/logout">Uitloggen</a> `, userInfo.Name, userInfo.Email, userInfo.Picture) } else { http.Error(w, "Ongeldige sessie", http.StatusUnauthorized) } } func logoutHandler(w http.ResponseWriter, r *http.Request) { // Verwijder cookie http.SetCookie(w, &http.Cookie{ Name: "oauth_token", Value: "", Path: "/", MaxAge: -1, }) http.Redirect(w, r, "/", http.StatusSeeOther) } ``` ## 7. Environment variables configuratie Maak een `.env` bestand of stel environment variables in: ```bash export GOOGLE_CLIENT_ID="je-client-id.apps.googleusercontent.com" export GOOGLE_CLIENT_SECRET="je-client-secret" ``` ## 8. Beveiligingsoverwegingen 1. **State parameter**: Gebruik altijd een cryptografisch veilige state parameter 2. **HTTPS**: Gebruik altijd HTTPS in productie 3. **Token opslag**: Sla tokens veilig op (httpOnly cookies) 4. **Token refresh**: Implementeer token refresh logica 5. **CSRF bescherming**: Voeg CSRF tokens toe aan formulieren ## 9. Uitgebreide token validatie ```go // Verbeterde token validatie met refresh func validateAndRefreshToken(accessToken string, refreshToken string) (string, error) { token := &oauth2.Token{ AccessToken: accessToken, RefreshToken: refreshToken, } // Maak een token source die automatisch refresh tokenSource := googleOauthConfig.TokenSource(context.Background(), token) newToken, err := tokenSource.Token() if err != nil { return "", err } return newToken.AccessToken, nil } ``` Deze implementatie biedt een complete OAuth2 integratie met Google in je Go applicatie. Vergeet niet om de client ID en secret te vervangen door je eigen credentials van Google Cloud Console.