Created
December 30, 2023 09:33
-
-
Save goodylili/53feefb8ed0ca3bb821b298f38925b9e to your computer and use it in GitHub Desktop.
GitLab Oauth Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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