Skip to content

Instantly share code, notes, and snippets.

@goodylili
Created December 30, 2023 09:33
Show Gist options
  • Save goodylili/53feefb8ed0ca3bb821b298f38925b9e to your computer and use it in GitHub Desktop.
Save goodylili/53feefb8ed0ca3bb821b298f38925b9e to your computer and use it in GitHub Desktop.
GitLab Oauth Example
package main
import (
"context"
"encoding/json"
"fmt"
"golang.org/x/oauth2"
"io"
"net/http"
)
var (
// Configuration for GitLab OAuth
GitLabOAuthConfig = &oauth2.Config{
RedirectURL: "http://localhost:8080/auth/callback", // Update this URL as needed
ClientID: "", // Replace with your GitLab Client ID
ClientSecret: "", // Replace with your GitLab Client Secret
Scopes: []string{"read_user"},
Endpoint: oauth2.Endpoint{
AuthURL: "https://gitlab.com/oauth/authorize",
TokenURL: "https://gitlab.com/oauth/token",
},
}
oauthStateString = "random" // Replace this with a random state string for production
)
// GitLabUser represents the GitLab user information
type GitLabUser struct {
ID int `json:"id"`
Username string `json:"username"`
AvatarURL string `json:"avatar_url"`
Email string `json:"email"`
}
// HandleGitLabLogin redirects the user to the GitLab login page
func HandleGitLabLogin(w http.ResponseWriter, r *http.Request) {
url := GitLabOAuthConfig.AuthCodeURL(oauthStateString)
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}
// HandleGitLabCallback processes the OAuth callback from GitLab
func HandleGitLabCallback(w http.ResponseWriter, r *http.Request) {
user, err := GetUserInfo(r.URL.Query().Get("state"), r.URL.Query().Get("code"))
if err != nil {
fmt.Println(err.Error())
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
jsonData, err := json.Marshal(user)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(jsonData)
}
// GetUserInfo retrieves the user information from GitLab
func GetUserInfo(state string, code string) (GitLabUser, error) {
var user GitLabUser
if state != oauthStateString {
return user, fmt.Errorf("invalid oauth state")
}
token, err := GitLabOAuthConfig.Exchange(context.Background(), code)
if err != nil {
return user, fmt.Errorf("code exchange failed: %s", err.Error())
}
client := http.Client{}
req, err := http.NewRequest("GET", "https://gitlab.com/api/v4/user", nil)
if err != nil {
return user, fmt.Errorf("failed creating request: %s", err.Error())
}
req.Header.Set("Authorization", "Bearer "+token.AccessToken)
resp, err := client.Do(req)
if err != nil {
return user, fmt.Errorf("failed getting user info: %s", err.Error())
}
defer resp.Body.Close()
contents, err := io.ReadAll(resp.Body)
if err != nil {
return user, fmt.Errorf("failed reading response body: %s", err.Error())
}
err = json.Unmarshal(contents, &user)
if err != nil {
return user, fmt.Errorf("failed unmarshalling user info: %s", err.Error())
}
return user, nil
}
func main() {
http.HandleFunc("/login", HandleGitLabLogin)
http.HandleFunc("/auth/callback", HandleGitLabCallback)
fmt.Println("Starting server on :8080...")
http.ListenAndServe(":8080", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment