Last active
September 5, 2020 05:13
-
-
Save santosh/4a244d0457390853ba598039f6c119a1 to your computer and use it in GitHub Desktop.
Webpage OAuth flow example with GitHub.
This file contains hidden or 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 ( | |
"encoding/json" | |
"fmt" | |
"net/http" | |
"os" | |
) | |
const clientID = "<your client id here>" | |
const clientSecret = "<your client secret here>" | |
func main() { | |
fs := http.FileServer(http.Dir("public")) | |
http.Handle("/", fs) | |
// We will be using `httpClient` to make external HTTP requests later in our code | |
httpClient := http.Client{} | |
// Create a nwe redirect route route | |
http.HandleFunc("/oauth/redirect", func(w http.ResponseWriter, r *http.Request) { | |
// First we neet to get the value of the `code` query param | |
err := r.ParseForm() | |
if err != nil { | |
fmt.Fprintf(os.Stdout, "could not parse query: %v", err) | |
w.WriteHeader(http.StatusBadRequest) | |
} | |
code := r.FormValue("code") | |
// Next, lets for the HTTP request to call the github oauth endpoint | |
// to get our access token | |
reqURL := fmt.Sprintf("https://github.com/login/oauth/access_token?client_id=%s&client_secret=%s&code=%s", clientID, clientSecret, code) | |
req, err := http.NewRequest(http.MethodPost, reqURL, nil) | |
if err != nil { | |
fmt.Fprintf(os.Stdout, "could not create HTTP request: %v", err) | |
w.WriteHeader(http.StatusBadRequest) | |
} | |
// We set this header since we want the response at JSON | |
req.Header.Set("accept", "application/json") | |
// Send out the HTTP request | |
res, err := httpClient.Do(req) | |
if err != nil { | |
fmt.Fprintf(os.Stdout, "could not sed HTTP request: %v", err) | |
w.WriteHeader(http.StatusInternalServerError) | |
} | |
defer res.Body.Close() | |
// Parse the request body into the `OAuthAccessResponse` struct | |
var t OAuthAccessResponse | |
if err := json.NewDecoder(res.Body).Decode(&t); err != nil { | |
fmt.Fprintf(os.Stdout, "could not parse JSON response: %v", err) | |
w.WriteHeader(http.StatusBadRequest) | |
} | |
// Finally, send a response to redicet the user to the welcome page | |
// with the access token | |
w.Header().Set("Location", "/welcome.html?access_token="+t.AccessToken) | |
w.WriteHeader(http.StatusFound) | |
}) | |
http.ListenAndServe(":8080", nil) | |
} | |
type OAuthAccessResponse struct { | |
AccessToken string `json:"access_token"` | |
} |
This file contains hidden or 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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Login with GitHub</title> | |
</head> | |
<body> | |
<a href="https://github.com/login/oauth/authorize?client_id=<your client id here>&redirect_uri=http://localhost:8080/oauth/redirect">Login with GitHub</a> | |
</body> | |
</html> |
This file contains hidden or 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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Hello</title> | |
</head> | |
<body> | |
</body> | |
<script> | |
// We can get the token from the "access_token" query | |
// param, available in the browesers "location" global | |
const query = window.location.search.substring(1) | |
const token = query.split('access_token=')[1] | |
// Call the user info API using the fetch browser library | |
fetch('https://api.github.com/user', { | |
headers: { | |
// Include the token in the Authorization header | |
Authorization: 'token ' + token | |
} | |
}) | |
// Parse the response as JSON | |
.then(res => res.json()) | |
.then(res => { | |
// Once we get the response (which has many fields) | |
// Documented here: https://developer.github.com/v3/users/#get-the-authenticated-user | |
// Write "Welcome <user name>" to the documents body | |
const nameNode = document.createTextNode(`Welcome, ${res.name}`) | |
document.body.appendChild(nameNode) | |
}) | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
HTML files are supposed to be in
public
subdir.