├── .gitignore
├── go.mod
├── public
├── index.html
└── welcome.html
├── README.md
└── main.go
/.gitignore:
--------------------------------------------------------------------------------
1 | tmp*
2 | go-oauth-example
3 | .vscode
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/sohamkamani/go-oauth-example
2 |
3 | go 1.16
4 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Go OAuth2 Example
8 |
9 |
10 |
11 |
12 |
13 |
14 | Login with github
15 |
16 |
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Go OAuth Example
2 |
3 | Read the blog post [here](https://www.sohamkamani.com/golang/oauth)
4 |
5 | This is an example node application that implements Githubs OAuth2 API.
6 |
7 | In order to run the application:
8 |
9 | 1. Register your new application on Github : https://github.com/settings/applications/new. In the "callback URL" field, enter "http://localhost:8080/oauth/redirect". Once you register, you will get a client ID and client secret.
10 | 2. Replace the values of the `clientID` and `clientSecret` variables in the [main.go](/main.go) file and also the [index.html](https://github.com/sohamkamani/go-oauth-example/blob/master/public/index.html#L14) file
11 | 4. Start the server by executing `go run main.go`
12 | 5. Navigate to http://localhost:8080 on your browser.
13 |
--------------------------------------------------------------------------------
/public/welcome.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Hello
9 |
10 |
11 |
12 |
13 |
14 |
37 |
38 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "net/http"
7 | "os"
8 | )
9 |
10 | const clientID = ""
11 | const clientSecret = ""
12 |
13 | func main() {
14 | fs := http.FileServer(http.Dir("public"))
15 | http.Handle("/", fs)
16 |
17 | // We will be using `httpClient` to make external HTTP requests later in our code
18 | httpClient := http.Client{}
19 |
20 | // Create a new redirect route route
21 | http.HandleFunc("/oauth/redirect", func(w http.ResponseWriter, r *http.Request) {
22 | // First, we need to get the value of the `code` query param
23 | err := r.ParseForm()
24 | if err != nil {
25 | fmt.Fprintf(os.Stdout, "could not parse query: %v", err)
26 | w.WriteHeader(http.StatusBadRequest)
27 | return
28 | }
29 | code := r.FormValue("code")
30 |
31 | // Next, lets for the HTTP request to call the github oauth enpoint
32 | // to get our access token
33 | reqURL := fmt.Sprintf("https://github.com/login/oauth/access_token?client_id=%s&client_secret=%s&code=%s", clientID, clientSecret, code)
34 | req, err := http.NewRequest(http.MethodPost, reqURL, nil)
35 | if err != nil {
36 | fmt.Fprintf(os.Stdout, "could not create HTTP request: %v", err)
37 | w.WriteHeader(http.StatusBadRequest)
38 | return
39 | }
40 | // We set this header since we want the response
41 | // as JSON
42 | req.Header.Set("accept", "application/json")
43 |
44 | // Send out the HTTP request
45 | res, err := httpClient.Do(req)
46 | if err != nil {
47 | fmt.Fprintf(os.Stdout, "could not send HTTP request: %v", err)
48 | w.WriteHeader(http.StatusInternalServerError)
49 | return
50 | }
51 | defer res.Body.Close()
52 |
53 | // Parse the request body into the `OAuthAccessResponse` struct
54 | var t OAuthAccessResponse
55 | if err := json.NewDecoder(res.Body).Decode(&t); err != nil {
56 | fmt.Fprintf(os.Stdout, "could not parse JSON response: %v", err)
57 | w.WriteHeader(http.StatusBadRequest)
58 | return
59 | }
60 |
61 | // Finally, send a response to redirect the user to the "welcome" page
62 | // with the access token
63 | w.Header().Set("Location", "/welcome.html?access_token="+t.AccessToken)
64 | w.WriteHeader(http.StatusFound)
65 | })
66 |
67 | http.ListenAndServe(":8080", nil)
68 | }
69 |
70 | type OAuthAccessResponse struct {
71 | AccessToken string `json:"access_token"`
72 | }
73 |
--------------------------------------------------------------------------------