Skip to content

Instantly share code, notes, and snippets.

@jfcote87
Created January 30, 2015 22:59
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfcote87/89eca3032cd5f9705ba3 to your computer and use it in GitHub Desktop.
Save jfcote87/89eca3032cd5f9705ba3 to your computer and use it in GitHub Desktop.
package oauth2Sample
imports (
"fmt"
"log"
"net/http"
"golang.org/x/oauth2"
)
// UserOauthClient returns an oauth2 client for a specific user
func UserOAuthClient(ctx oauth2.Context, config auth2.Config, userId string) (client *http.Client, err error) {
var userToken *oauth2.Token
if userToken, err = getCachedToken(userId); err != nil {
// if token for user is not cached then go through oauth2 flow
if userToken, err = newUserToken(ctx, config, userId); err != nil {
return
}
}
if !userToken.Valid() { // if user token is expired
userToken = &oauth2.Token{ RefreshToken: userToken.RefreshToken }
}
return config.Client(ctx, userToken)
}
func getCachedToken(userId string) (*oauth2.Token, error) {
var tk *oauth2.Token
// logic to retrieve refresh token from your datastore
return tk, err
}
func newUserToken(ctx, config, userId) (*oauth2.Token, error) {
stateBytes := make([]byte, 32)
_, err := rand.Read(stateBytes)
if err != nil {
log.Fatalf("Unable to read random bytes: %v", err)
return nil, err
}
state := fmt.Sprintf("%x", stateBytes)
authUrl := config.AuthCodeURL(state)
//... your logic for handing retrieving code for oauth exchange and matching state
token, err := config.Exchange(oauth2.NoContext, authcode)
if err != nil {
log.Fatalf("Exchange error: %v", err)
return nil, err
}
saveToken(userId, token) // save token to datastore
return token, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment