1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| package main
import ( "context" "encoding/json" "fmt" "io" "log" "net/http"
"golang.org/x/oauth2" "golang.org/x/oauth2/github" )
var ( githubOauthConfig = &oauth2.Config{ ClientID: "Ov23liHgJhetSUt45V9r", ClientSecret: "ClientSecret", RedirectURL: "http://localhost:8080/callback", Endpoint: github.Endpoint, Scopes: []string{"user:email"}, } oauthStateString = "random" )
func main() { http.HandleFunc("/", handleMain) http.HandleFunc("/login", handleGitHubLogin) http.HandleFunc("/callback", handleGitHubCallback) http.HandleFunc("/logout", handleLogout) log.Println("Started running on http://localhost:8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
func handleMain(w http.ResponseWriter, r *http.Request) { var htmlIndex = `<html><body><a href="/login">Log in with GitHub</a></body></html>` io.WriteString(w, htmlIndex) }
func handleGitHubLogin(w http.ResponseWriter, r *http.Request) { url := githubOauthConfig.AuthCodeURL(oauthStateString) http.Redirect(w, r, url, http.StatusTemporaryRedirect) }
type GitHubUser struct { Login string `json:"login"` ID int `json:"id"` AvatarURL string `json:"avatar_url"` HTMLURL string `json:"html_url"` Name string `json:"name"` Company string `json:"company"` Blog string `json:"blog"` Location string `json:"location"` Email string `json:"email"` Bio string `json:"bio"` }
func handleGitHubCallback(w http.ResponseWriter, r *http.Request) { if r.FormValue("state") != oauthStateString { log.Println("invalid oauth state") http.Redirect(w, r, "/", http.StatusTemporaryRedirect) return }
token, err := githubOauthConfig.Exchange(context.Background(), r.FormValue("code")) if err != nil { log.Println("code exchange failed: ", err) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) return }
client := githubOauthConfig.Client(context.Background(), token) resp, err := client.Get("https://api.github.com/user") if err != nil { log.Println("failed getting user info: ", err) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) return } defer resp.Body.Close()
var user GitHubUser if err := json.NewDecoder(resp.Body).Decode(&user); err != nil { log.Println("failed decoding response body: ", err) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) return }
fmt.Fprintf(w, `<html><body> <h1>User Info</h1> <p><strong>Login:</strong> %s</p> <p><strong>ID:</strong> %d</p> <p><strong>Avatar URL:</strong> <img src="%s" alt="avatar" ></p> <p><strong>Profile URL:</strong> <a href="%s">%s</a></p> <p><strong>Name:</strong> %s</p> <p><strong>Company:</strong> %s</p> <p><strong>Blog:</strong> %s</p> <p><strong>Location:</strong> %s</p> <p><strong>Email:</strong> %s</p> <p><strong>Bio:</strong> %s</p> </body></html>`, user.Login, user.ID, user.AvatarURL, user.HTMLURL, user.HTMLURL, user.Name, user.Company, user.Blog, user.Location, user.Email, user.Bio) }
func handleLogout(w http.ResponseWriter, r *http.Request) { http.SetCookie(w, &http.Cookie{ Name: "github_oauth_token", Value: "", Path: "/", MaxAge: -1, }) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) }
|