OAuth is a specification that allows users to delegate access to their data without sharing their username and password with that service.
Learn how to implement authentication via Google in a Go web application.
First things first, we need to create our Google Project and create OAuth2 credentials.
- Go to Google Cloud Platform
- Create a new project or select one if you already have it.
- Go to Credentials and then create a new one choosing “OAuth client ID”
- Add "authorized redirect URL", for this example
localhost:8080/auth/google/callback
- Copy the client_id and client secret
Code
oauth2.Config example
1
2
3
4
5
6
7
8
9
10
googleOauth2Conf = &oauth2.Config{
ClientID: "your_google_client_id",
ClientSecret: "your_google_client_secret",
RedirectURL: "http://localhost:8080/auth/google/callback",
Scopes: []string{
"profile",
"email",
},
Endpoint: google.Endpoint,
}
Generate state
1
2
3
b := make([]byte, 16)
_, _ = rand.Read(b)
state := base64.URLEncoding.EncodeToString(b)
Get AuthCodeURL
with state
1
gotoUrl := googleOauth2Conf.AuthCodeURL(state)
Save state
at server and Redirect to gotoUrl
, which will redirect us to the google login page.
1
2
SetCookie("state", state)
Redirect(gotoUrl, 302)
After login with our google credentials, it will redirect back to our application and on the callback page, we can see the details of the logged-in user and can save this detail in a database for future use also.
Do in OAuthGoogleCallBack Handler
Get state
from cookie and check it with the value from FormValue
1
2
3
4
5
6
7
stateCookie := getCookie("state")
stateForm := r.FormValue("state")
if stateCookie != stateForm {
// invalid state
return
}
Get code
from FormValue and Exchange
Token with code.
1
2
code := r.FormValue("code")
token, err := googleOauth2Conf.Exchange(context.Background(), code)
Get user info with token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
oauthGoogleUrlAPI := "https://www.googleapis.com/oauth2/v2/userinfo?access_token="
client := googleOauth2Conf.Client(context.Background(), token)
response, err := client.Get(oauthGoogleUrlAPI + token.AccessToken)
if err != nil {
// err
return
}
defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
if err != nil {
// err
return
}
log.Println(string(contents))
ToDo with user info
Register or Login with the logined User info.