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) }
// 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) }
// 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 (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) if err != nil { log.Fatalf("Error when getting token permissions: %v", err) return nil, err } token, err := c.HandleOAuthCode(authcode) if err != nil { log.Fatalf("Error when handling OAuth Code error: %v", err) return nil, err } c.SaveToken(userID, token) // save token to datastore return token, nil }
// Your credentials should be obtained from the Google // Developer Console (https://console.developers.google.com). func OauthURL(conf *oauth2.Config) string { // Redirect user to Google's consent page to ask for permission // for the scopes specified above. url := conf.AuthCodeURL("state") log.Debugf("\nVisit the URL for the auth dialog: %v\n", url) return url }
// 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 (c *googinitCmd) RunCommand(args []string) error { var ( err error clientId string clientSecret string oauthConfig *oauth2.Config ) if c.storageType != "drive" && c.storageType != "cloud" { return cmdmain.UsageError("Invalid storage type: must be drive for Google Drive or cloud for Google Cloud Storage.") } clientId, clientSecret = getClientInfo() switch c.storageType { case "drive": oauthConfig = &oauth2.Config{ Scopes: []string{drive.Scope}, Endpoint: google.Endpoint, ClientID: clientId, ClientSecret: clientSecret, RedirectURL: oauthutil.TitleBarRedirectURL, } case "cloud": oauthConfig = &oauth2.Config{ Scopes: []string{storage.ScopeReadWrite}, Endpoint: google.Endpoint, ClientID: clientId, ClientSecret: clientSecret, RedirectURL: oauthutil.TitleBarRedirectURL, } } token, err := oauth2.ReuseTokenSource(nil, &oauthutil.TokenSource{ Config: oauthConfig, AuthCode: func() string { fmt.Fprintf(cmdmain.Stdout, "Get auth code from:\n\n") fmt.Fprintf(cmdmain.Stdout, "%v\n\n", oauthConfig.AuthCodeURL("", oauth2.AccessTypeOffline, oauth2.ApprovalForce)) return prompt("Enter auth code:") }, }).Token() if err != nil { return fmt.Errorf("could not acquire token: %v", err) } fmt.Fprintf(cmdmain.Stdout, "\nYour Google auth object:\n\n") enc := json.NewEncoder(cmdmain.Stdout) authObj := map[string]string{ "client_id": clientId, "client_secret": clientSecret, "refresh_token": token.RefreshToken, } enc.Encode(authObj) fmt.Fprint(cmdmain.Stdout, "\n\nFor server-config.json, your 'googlecloudstorage' value (update with your bucket name and path):\n\n") fmt.Fprintf(cmdmain.Stdout, "%s:%s:%s:bucketName[/optional/dir]\n", clientId, clientSecret, token.RefreshToken) return nil }
func RegisterOAuth(name string, config *oauth2.Config, newInstance func([]string, *oauth2.Token) (Instance, error), instType reflect.Type) { protocols[name] = &Protocol{ Params: &Params{ OAuthURL: config.AuthCodeURL(""), }, OAuth: config, newInstance: newInstance, instType: instType, } }
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 login(f *oauth2.Config, s session.Store, w http.ResponseWriter, r *http.Request) { next := extractPath(r.URL.Query().Get(keyNextPage)) if s.Get(keyToken) == nil { // User is not logged in. if next == "" { next = "/" } http.Redirect(w, r, f.AuthCodeURL(next), codeRedirect) return } // No need to login, redirect to the next page. http.Redirect(w, r, next, codeRedirect) }
func loginWeChat(f *oauth2.Config, s sessions.Session, w http.ResponseWriter, r *http.Request) { next := extractPath(r.URL.Query().Get(keyNextPage)) if s.Get(keyToken) == nil { // User is not logged in. if next == "" { next = "/" } http.Redirect(w, r, strings.Replace(f.AuthCodeURL(next), "client_id", "appid", -1), codeRedirect) return } // No need to login, redirect to the next page. http.Redirect(w, r, next, codeRedirect) }
// 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 }
func (p *Engine) getSiteInfo(c *gin.Context) { lng := c.MustGet("locale").(string) ifo := p._siteInfoMap(lng) var gcf oauth2.Config if err := p.Dao.Get("google.oauth", &gcf); err != nil { p.Logger.Error(err) } ifo["oauth2"] = map[string]string{ "google": gcf.AuthCodeURL(p.Oauth2GoogleState), } c.JSON(http.StatusOK, ifo) }
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 }
// 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 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 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 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 }
// LoginHandler handles OAuth2 login requests by reading the state value from // the ctx and redirecting requests to the AuthURL with that state value. func LoginHandler(config *oauth2.Config, failure ctxh.ContextHandler) ctxh.ContextHandler { if failure == nil { failure = gologin.DefaultFailureHandler } fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) { state, err := StateFromContext(ctx) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } authURL := config.AuthCodeURL(state) http.Redirect(w, req, authURL, http.StatusFound) } return ctxh.ContextHandlerFunc(fn) }
//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 GetAuthCodeURL(conf oauth2.Config, ar *osin.AuthorizeRequest, provider string) string { redirect, err := url.Parse(conf.RedirectURL) if err != nil { return "" } q := redirect.Query() q.Set(ProviderQueryParam, provider) q.Set(RedirectQueryParam, ar.RedirectUri) q.Set(ClientQueryParam, ar.Client.GetId()) q.Set(ScopeQueryParam, ar.Scope) q.Set(StateQueryParam, ar.State) q.Set(TypeQueryParam, string(ar.Type)) redirect.RawQuery = q.Encode() conf.RedirectURL = redirect.String() return conf.AuthCodeURL(ar.State) }
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 }
// Get an authorization code by opening up the authorization page in a web // browser. func codeFromWeb(oauthConfig *oauth2.Config) (string, error) { ch := make(chan string) randState := fmt.Sprintf("st%d", time.Now().UnixNano()) // Launch a local web server to receive the authorization code. ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { if req.URL.Path == "/favicon.ico" { http.Error(rw, "", 404) 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 != "" { fmt.Fprintf(rw, "<h1>Success!</h1>Skicka is now authorized.") rw.(http.Flusher).Flush() ch <- code return } http.Error(rw, "", 500) })) defer ts.Close() oauthConfig.RedirectURL = ts.URL url := oauthConfig.AuthCodeURL(randState) errs := make(chan error) go func() { err := openURL(url) errs <- err }() err := <-errs if err == nil { // The URL open was apparently successful; wait for our server to // receive the code and send it back. code := <-ch return code, nil } return "", err }
func login(config *oauth2.Config, s sessions.Session, w http.ResponseWriter, r *http.Request) { next := extractPath(r.URL.Query().Get(keyNextPage)) if s.Get(keyToken) == nil { // User is not logged in. if next == "" { next = "/" } state := newState() // store the next url and state token in the session s.Set(keyState, state) s.Set(keyNextPage, next) http.Redirect(w, r, config.AuthCodeURL(state, oauth2.AccessTypeOffline), http.StatusFound) return } // No need to login, redirect to the next page. http.Redirect(w, r, next, http.StatusFound) }
// 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) }
// 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 }