func exchangeToken(ctx context.Context, config *oauth2.Config, code string) *oauth2.Token { token, err := config.Exchange(ctx, code) if err != nil { glog.Fatalf("Token exchange error: %v", err) } return token }
func handleOAuth2Callback(config *oauth2.Config, s sessions.Session, w http.ResponseWriter, r *http.Request) { providedState := extractPath(r.URL.Query().Get("state")) //verify that the provided state is the state we generated //if it is not, then redirect to the error page originalState := s.Get(keyState) if providedState != originalState { http.Redirect(w, r, PathError, http.StatusFound) return } next := s.Get(keyNextPage).(string) code := r.URL.Query().Get("code") t, err := config.Exchange(oauth2.NoContext, code) if err != nil { // Pass the error message, or allow dev to provide its own // error handler. http.Redirect(w, r, PathError, http.StatusFound) return } // Store the credentials in the session. val, _ := json.Marshal(t) s.Set(keyToken, val) http.Redirect(w, r, next, http.StatusFound) }
// Config does the initial creation of the token func Config(name string, config *oauth2.Config) error { // See if already have a token tokenString := fs.ConfigFile.MustValue(name, "token") if tokenString != "" { fmt.Printf("Already have a token - refresh?\n") if !fs.Confirm() { return nil } } // Generate a URL for the user to visit for authorization. authUrl := config.AuthCodeURL("state") fmt.Printf("Go to the following link in your browser\n") fmt.Printf("%s\n", authUrl) fmt.Printf("Log in, then type paste the token that is returned in the browser here\n") // Read the code, and exchange it for a token. fmt.Printf("Enter verification code> ") authCode := fs.ReadLine() token, err := config.Exchange(oauth2.NoContext, authCode) if err != nil { return fmt.Errorf("Failed to get token: %v", err) } return putToken(name, token) }
func (p *Engine) _google(code string) (*User, error) { var cfg oauth2.Config if err := p.Dao.Get("google.oauth", &cfg); err != nil { return nil, err } tok, err := cfg.Exchange(oauth2.NoContext, code) if err != nil { return nil, err } cli := cfg.Client(oauth2.NoContext, tok) res, err := cli.Get("https://www.googleapis.com/oauth2/v1/userinfo?alt=json") if err != nil { return nil, err } defer res.Body.Close() var gu GoogleUser dec := json.NewDecoder(res.Body) if err := dec.Decode(&gu); err != nil { return nil, err } return p.Dao.AddUser(gu.ID, "google", gu.Email, gu.Name, gu.Link, gu.Picture) }
func tokenFromWeb(ctx context.Context, config *oauth2.Config) *oauth2.Token { randState := fmt.Sprintf("st%d", time.Now().UnixNano()) tokenOnce.Do(func() { http.HandleFunc("/oauth/", func(rw http.ResponseWriter, req *http.Request) { if req.FormValue("state") != randState { log.Printf("State doesn't match: req = %#v", req) http.Error(rw, "", 500) return } if code := req.FormValue("code"); code != "" { fmt.Fprintf(rw, "<h1>Success</h1>Authorized.") rw.(http.Flusher).Flush() ch <- code return } log.Printf("no code") http.Error(rw, "", 500) }) }) config.RedirectURL = "http://localhost:8383/oauth/" authURL := config.AuthCodeURL(randState) go openURL(authURL) log.Printf("Authorize this app at: %s", authURL) code := <-ch log.Printf("Got code: %s", code) token, err := config.Exchange(ctx, code) if err != nil { log.Fatalf("Token exchange error: %v", err) } return token }
// Ref: https://github.com/google/google-api-go-client/blob/master/examples/calendar.go // Copyright 2014 The Go Authors. All rights reserved. func tokenFromWeb(ctx context.Context, config *oauth2.Config) (*oauth2.Token, error) { ch := make(chan string) randState := fmt.Sprintf("st%d", time.Now().UnixNano()) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/favicon.ico" { w.WriteHeader(http.StatusNotFound) return } if r.FormValue("state") != randState { w.WriteHeader(http.StatusInternalServerError) return } if code := r.FormValue("code"); code != "" { w.Write([]byte("<h1>Success</h1>Authorized.")) w.(http.Flusher).Flush() ch <- code return } // no code w.WriteHeader(http.StatusInternalServerError) })) defer ts.Close() config.RedirectURL = ts.URL authURL := config.AuthCodeURL(randState) fmt.Println("Access to %s", authURL) code := <-ch return config.Exchange(ctx, code) }
func GetTokenFromCode(config *oauth2.Config, code string) (*oauth2.Token, error) { token, err := config.Exchange(oauth2.NoContext, code) if err != nil { return nil, err } return token, nil }
// CallbackHandler handles OAuth2 redirection URI requests by parsing the auth // code and state, comparing with the state value from the ctx, and obtaining // an OAuth2 Token. func CallbackHandler(config *oauth2.Config, success, failure ctxh.ContextHandler) ctxh.ContextHandler { if failure == nil { failure = gologin.DefaultFailureHandler } fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) { authCode, state, err := parseCallback(req) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } ownerState, err := StateFromContext(ctx) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } if state != ownerState || state == "" { ctx = gologin.WithError(ctx, ErrInvalidState) failure.ServeHTTP(ctx, w, req) return } // use the authorization code to get a Token token, err := config.Exchange(ctx, authCode) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } ctx = WithToken(ctx, token) success.ServeHTTP(ctx, w, req) } return ctxh.ContextHandlerFunc(fn) }
// getTokenFromWeb uses Config to request a Token. // It returns the retrieved Token. func getTokenFromWeb(config *oauth2.Config) *oauth2.Token { ch := make(chan string) http.HandleFunc("/auth", func(rw http.ResponseWriter, req *http.Request) { if code := req.FormValue("code"); code != "" { fmt.Fprintf(rw, "<h1>Success</h1>Authorized.") rw.(http.Flusher).Flush() ch <- code return } log.Printf("no code") http.Error(rw, "", 500) }) authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline) go openUrl(authURL) log.Printf("Authorize this app at: %s", authURL) code := <-ch log.Printf("received code") tok, err := config.Exchange(oauth2.NoContext, code) if err != nil { log.Fatalf("Unable to retrieve token from web %v", err) } return tok }
func ExecuteFlow(ctx context.Context, config *oauth2.Config, options ...Option) (*oauth2.Token, error) { o := processOpts(options) configCopy := *config config = &configCopy code := make(chan string) l, err := net.Listen("tcp", o.addr) if err != nil { return nil, err } defer l.Close() config.RedirectURL = fmt.Sprintf("http://%s/", l.Addr().String()) go http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, closeMessage) code <- r.FormValue("code") // send code to OAuth flow })) url := config.AuthCodeURL("", oauth2.AccessTypeOffline) if o.noBrowser { fmt.Fprintln(os.Stderr, visitMessage) } else if err := openURL(url); err != nil { fmt.Fprintln(os.Stderr, visitMessage) } else { fmt.Fprintln(os.Stderr, openedMessage) } fmt.Fprintf(os.Stderr, "\n%s\n\n", url) fmt.Fprintln(os.Stderr, resumeMessage) return config.Exchange(ctx, <-code) }
func handleCallback(w http.ResponseWriter, r *http.Request, config *oauth2.Config, profilesURL, code string) { token, err := config.Exchange(oauth2.NoContext, code) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } client := config.Client(oauth2.NoContext, token) response, err := client.Get(profilesURL) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer response.Body.Close() rawBody, err := ioutil.ReadAll(response.Body) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } s, _ := session.Manager.SessionStart(w, r) defer s.SessionRelease(w) s.Set("id_token", token.Extra("id_token")) s.Set("access_token", token.AccessToken) s.Set("profile", string(rawBody)) http.Redirect(w, r, "/user", http.StatusMovedPermanently) }
func handleOAuth2Callback(config *oauth2.Config, s sessions.Session, w http.ResponseWriter, r *http.Request) { providedState := extractPath(r.URL.Query().Get("state")) //fmt.Printf("Got state from request %s\n", providedState) //verify that the provided state is the state we generated //if it is not, then redirect to the error page originalState := s.Get(keyState) //fmt.Printf("Got state from session %s\n", originalState) if providedState != originalState { //http.Redirect(w, r, PathError, http.StatusFound) //return } //next := s.Get(keyNextPage).(string) //fmt.Printf("Got a next page from the session: %s\n", next) next := "" code := r.URL.Query().Get("code") t, err := config.Exchange(oauth2.NoContext, code) if err != nil { // Pass the error message, or allow dev to provide its own // error handler. fmt.Println("There is some error in the code exchange") http.Redirect(w, r, PathError, http.StatusFound) return } // Store the credentials in the session. val, _ := json.Marshal(t) s.Set(KeyToken, maskval(val)) http.Redirect(w, r, next, http.StatusFound) }
// authorize performs user authorization flow, asking for permissions grant. func authorize(conf *oauth2.Config) (*oauth2.Token, error) { aurl := conf.AuthCodeURL("unused", oauth2.AccessTypeOffline) fmt.Printf("Authorize me at following URL, please:\n\n%s\n\nCode: ", aurl) var code string if _, err := fmt.Scan(&code); err != nil { return nil, err } return conf.Exchange(context.Background(), code) }
func main() { ctx := context.Background() provider, err := oidc.NewProvider(ctx, "https://accounts.google.com") if err != nil { log.Fatal(err) } config := oauth2.Config{ ClientID: clientID, ClientSecret: clientSecret, Endpoint: provider.Endpoint(), RedirectURL: "http://127.0.0.1:5556/auth/google/callback", Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, } state := "foobar" // Don't do this in production. http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, config.AuthCodeURL(state), http.StatusFound) }) http.HandleFunc("/auth/google/callback", func(w http.ResponseWriter, r *http.Request) { if r.URL.Query().Get("state") != state { http.Error(w, "state did not match", http.StatusBadRequest) return } oauth2Token, err := config.Exchange(ctx, r.URL.Query().Get("code")) if err != nil { http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError) return } userInfo, err := provider.UserInfo(ctx, oauth2.StaticTokenSource(oauth2Token)) if err != nil { http.Error(w, "Failed to get userinfo: "+err.Error(), http.StatusInternalServerError) return } resp := struct { OAuth2Token *oauth2.Token UserInfo *oidc.UserInfo }{oauth2Token, userInfo} data, err := json.MarshalIndent(resp, "", " ") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(data) }) log.Printf("listening on http://%s/", "127.0.0.1:5556") log.Fatal(http.ListenAndServe("127.0.0.1:5556", nil)) }
func auth(conf *oauth2.Config) (*oauth2.Token, error) { url := conf.AuthCodeURL("", oauth2.AccessTypeOffline) fmt.Printf("Visit the URL for the auth dialog: %v\n", url) reader := bufio.NewReader(os.Stdin) fmt.Printf("Enter the authorization code: ") code, _ := reader.ReadString('\n') token, err := conf.Exchange(oauth2.NoContext, code) if err != nil { return nil, err } return token, nil }
// getTokenFromWeb uses Config to request a Token. // It returns the retrieved Token. func getTokenFromWeb(config *oauth2.Config) *oauth2.Token { authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline) go exec.Command("xdg-open", authURL).Run() out, err := exec.Command("zenity", "--entry", "--title=Gmail Access", "--text=Type the authorization code from "+ "your browser:").Output() if err != nil { log.Fatalf("Unable to read authorization code %v", err) } tok, err := config.Exchange(oauth2.NoContext, string(out)) if err != nil { log.Fatalf("Unable to retrieve token from web %v", err) } return tok }
// newCachingTokenSource creates a new instance of CachingTokenSource that // caches the token in cacheFilePath. ctx and config are used to create and // retrieve the token in the first place. // If no token is available it will run though the oauth flow for an // installed app. func newCachingTokenSource(cacheFilePath string, ctx context.Context, config *oauth2.Config) (oauth2.TokenSource, error) { var tok *oauth2.Token = nil var err error if cacheFilePath == "" { glog.Warningf("cacheFilePath is empty. Not caching auth token.") } else if _, err = os.Stat(cacheFilePath); err == nil { // If the file exists. Load from disk. f, err := os.Open(cacheFilePath) if err != nil { return nil, err } tok = &oauth2.Token{} if err = json.NewDecoder(f).Decode(tok); err != nil { return nil, err } } else if !os.IsNotExist(err) { return nil, err } // If there was no token, we run through the flow. if tok == nil { // Run through the flow. url := config.AuthCodeURL("state", oauth2.AccessTypeOffline) fmt.Printf("Your browser has been opened to visit:\n\n%s\n\nEnter the verification code:", url) var code string if _, err = fmt.Scan(&code); err != nil { return nil, err } tok, err = config.Exchange(ctx, code) if err != nil { return nil, err } if err = saveToken(cacheFilePath, tok); err != nil { return nil, err } glog.Infof("token: %v", tok) } // We have a token at this point. tokenSource := config.TokenSource(ctx, tok) return &cachingTokenSource{ cacheFilePath: cacheFilePath, tokenSource: tokenSource, lastToken: tok, }, nil }
// getTokenFromWeb uses Config to request a Token. // It returns the retrieved Token. func getTokenFromWeb(config *oauth2.Config) *oauth2.Token { authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline) fmt.Println(authURL) var code string if _, err := fmt.Scan(&code); err != nil { log.Fatalf("Unable to read authorization code %v", err) } tok, err := config.Exchange(oauth2.NoContext, code) if err != nil { log.Fatalf("Unable to retrieve token from web %v", err) } return tok }
func handleOAuth2Callback(f *oauth2.Config, s session.Store, w http.ResponseWriter, r *http.Request) { next := extractPath(r.URL.Query().Get("state")) code := r.URL.Query().Get("code") t, err := f.Exchange(oauth2.NoContext, code) if err != nil { // Pass the error message, or allow dev to provide its own // error handler. http.Redirect(w, r, PathError, codeRedirect) return } // Store the credentials in the session. val, _ := json.Marshal(t) s.Set(keyToken, val) http.Redirect(w, r, next, codeRedirect) }
func tokenFromWeb(ctx context.Context, config *oauth2.Config, wf *web.WebFace) *oauth2.Token { ch := make(chan string) randState := fmt.Sprintf("st%d", time.Now().UnixNano()) config.RedirectURL = "http://" + wf.Addr + "/login" { // Auto authURL := config.AuthCodeURL(randState) wf.RedirectHandler = func(rw http.ResponseWriter, req *http.Request) { if req.URL.Path == "/favicon.ico" { http.Error(rw, "", 404) return } if !strings.HasPrefix(req.URL.Path, "/login") { log.Println("Redirect ", req.URL.Path, strings.HasPrefix(req.URL.Path, "/login")) http.Redirect(rw, req, authURL, 302) return } if req.FormValue("state") != randState { log.Printf("State doesn't match: req = %#v", req) http.Error(rw, "", 500) return } if code := req.FormValue("code"); code != "" { wf.RedirectHandler = nil http.Redirect(rw, req, "http://"+wf.Addr+"/", 302) ch <- code return } } log.Println("Awaiting Authorize Token") } code := <-ch log.Printf("Got code: %s", code) token, err := config.Exchange(ctx, code) if err != nil { log.Fatalf("Token exchange error: %v", err) } return token }
func tokenFromWeb(ctx context.Context, config *oauth2.Config) { randState := fmt.Sprintf("st%d", time.Now().UnixNano()) config.RedirectURL = "http://localhost:3000/after" http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) { log.Printf("====> Got: %s", req.URL.Path) if req.URL.Path == "/favicon.ico" { http.Error(rw, "", 404) return } if req.URL.Path == "/" { authURL := config.AuthCodeURL(randState) http.Redirect(rw, req, authURL, http.StatusFound) } if req.FormValue("state") != randState { log.Printf("State doesn't match: %s / %s ", req.FormValue("state"), randState) http.Error(rw, "", 500) return } if code := req.FormValue("code"); code != "" { log.Printf("sending code") token, err := config.Exchange(ctx, code) if err == nil { // encode this thing var tokenBytes bytes.Buffer enc := gob.NewEncoder(&tokenBytes) enc.Encode(token) tokenString := base64.StdEncoding.EncodeToString(tokenBytes.Bytes()) log.Printf(tokenString) } log.Printf("sent code") fmt.Fprintf(rw, "<h1>Success</h1>Authorized.") return } log.Printf("no code") http.Error(rw, "", 500) }) http.ListenAndServe(":3000", nil) }
func GetGCloudTokenViaWebUI(conf *oauth2.Config) (*oauth2.Token, error) { authurl := conf.AuthCodeURL("fixmeee", oauth2.AccessTypeOffline) fmt.Printf("visit %v\n", authurl) fmt.Printf("paste code:") var code string if _, err := fmt.Scan(&code); err != nil { return nil, fmt.Errorf("Failed to scan auth code: %v", err) } token, err := conf.Exchange(oauth2.NoContext, code) if err != nil { return nil, fmt.Errorf("Failed to use auth code: %v", err) } return token, nil }
// getTokenFromWeb uses Config to request a Token. // It returns the retrieved Token. func getTokenFromWeb(config *oauth2.Config) *oauth2.Token { authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline) fmt.Printf("Go to the following link in your browser then type the "+ "authorization code: \n%v\n", authURL) var code string if _, err := fmt.Scan(&code); err != nil { log.Fatalf("Unable to read authorization code %v", err) } tok, err := config.Exchange(oauth2.NoContext, code) if err != nil { log.Fatalf("Unable to retrieve token from web %v", err) } return tok }
func auth(cfg *oauth2.Config, fn func(string) error) (*oauth2.Token, error) { ch := make(chan interface{}) l, err := net.Listen("tcp", ":0") if err != nil { return nil, err } defer l.Close() cfg.RedirectURL = urlFor(l.Addr()) if err := fn(cfg.RedirectURL); err != nil { return nil, err } go func() { for { c, err := l.Accept() if err != nil { ch <- err return } code, err := serveConn(c, cfg) if err != nil { ch <- err return } if code == "" { continue } ch <- code return } }() v := <-ch switch t := v.(type) { case error: return nil, t case string: return cfg.Exchange(context.Background(), t) } panic("unreachable") }
//User authorization with Google func auth(conf *oauth2.Config, port string) *oauth2.Token { // Redirect user to consent page to ask for permission // for the scopes specified above. url := conf.AuthCodeURL("state", oauth2.AccessTypeOffline) var err error switch runtime.GOOS { case "linux": err = exec.Command("xdg-open", url).Start() // println("LINUX") case "windows", "darwin": err = exec.Command("open", url).Start() // println("MAC") default: err = fmt.Errorf("unsupported platform") // println("DEFAULT") } // Use the authorization code that is pushed to the redirect URL. // NewTransportWithCode will do the handshake to retrieve // an access token and initiate a Transport that is // authorized and authenticated by the retrieved token. c := make(chan string) http.HandleFunc("/finished", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() q := r.URL.Query() c <- q["code"][0] }) go http.ListenAndServe(":"+port, nil) code := <-c fmt.Printf("Successfully received code") tok, err := conf.Exchange(oauth2.NoContext, code) if err != nil { log.Fatal(err) } else { fmt.Println("Valid user - Successfully exchanged code for token") } return tok }
func createNewToken(cfg *oauth2.Config) (*oauth2.Token, error) { url := cfg.AuthCodeURL("mystatetoken", oauth2.AccessTypeOffline) fmt.Println("Please paste the token obtained from", url, "here:") var code string _, err := fmt.Scan(&code) if err != nil { return nil, err } token, err := cfg.Exchange(oauth2.NoContext, code) if err != nil { return nil, err } return token, nil }
// Have the user authorize skicka and return the resulting token. tryBrowser // controls whether the function tries to open a tab in a web browser or // prints instructions to tell the user how to authorize manually. func authorizeAndGetToken(oauthConfig *oauth2.Config, tryBrowser bool) (*oauth2.Token, error) { var code string var err error if tryBrowser { fmt.Printf("skicka: attempting to launch browser to authorize.\n") fmt.Printf("(Re-run skicka with the -no-browser-auth option to authorize directly.)\n") if code, err = codeFromWeb(oauthConfig); err != nil { return nil, err } } else { randState := fmt.Sprintf("st%d", time.Now().UnixNano()) url := oauthConfig.AuthCodeURL(randState) fmt.Printf("Go to the following link in your browser:\n%v\n", url) fmt.Printf("Enter verification code: ") fmt.Scanln(&code) } return oauthConfig.Exchange(oauth2.NoContext, code) }
func (c *client) newUserToken(ctx context.Context, config *oauth2.Config, userID string) (*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, oauth2.AccessTypeOffline) authcode, err := c.GiveTokenPermissions(authURL) token, err := config.Exchange(oauth2.NoContext, authcode) if err != nil { log.Fatalf("Exchange error: %v", err) return nil, err } c.SaveToken(userID, token) // save token to datastore return token, nil }
func handleOAuth2Callback(store *sessions.CookieStore, config *oauth2.Config, token string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if st := r.FormValue("state"); st != token { http.Error(w, "Returned state token does not match.", 401) } t, err := config.Exchange(oauth2.NoContext, r.FormValue("code")) if err != nil { http.Error(w, err.Error(), 500) } session, _ := store.Get(r, "sndcld") session.Values["token"] = t.AccessToken session.Save(r, w) f, _ := os.Open("./layout.html") io.Copy(w, f) f.Close() } }
// getTokenFromWeb uses Config to request a Token. // It returns the retrieved Token. func getTokenFromWeb(config *oauth2.Config) *oauth2.Token { authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline) cmd := exec.Command("open", authURL) if err := cmd.Start(); err != nil { fmt.Errorf("Browser Start Error: %v\n", err) fmt.Errorf("Go to the following link in your browser.\n") } fmt.Printf("URL: %v\nType the authorization code.\n", authURL) var code string if _, err := fmt.Scan(&code); err != nil { log.Fatalf("Unable to read authorization code %v", err) } token, err := config.Exchange(oauth2.NoContext, code) if err != nil { log.Fatalf("Unable to retrieve token from web %v", err) } return token }