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
}
示例#2
0
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)
}
示例#3
0
文件: oauthutil.go 项目: X1011/rclone
// 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)
}
示例#4
0
文件: c_oauth2.go 项目: itpkg/chaos
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)
}
示例#5
0
文件: google.go 项目: d4l3k/campus
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
}
示例#6
0
// 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)
}
示例#7
0
文件: utils.go 项目: arturdent/goub
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
}
示例#8
0
文件: login.go 项目: gooops/gologin
// 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)
}
示例#9
0
// 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
}
示例#10
0
文件: flow.go 项目: broady/floauth
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)
}
示例#11
0
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)
}
示例#12
0
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)
}
示例#13
0
文件: auth.go 项目: aliafshar/tools
// 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)
}
示例#14
0
文件: app.go 项目: coreos/go-oidc
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))
}
示例#15
0
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
}
示例#16
0
文件: mail.go 项目: Rozakh/i3gobar
// 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
}
示例#17
0
// 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
}
示例#18
0
// 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
}
示例#19
0
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)
}
示例#20
0
文件: login.go 项目: Kimau/GoCam
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
}
示例#21
0
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)
}
示例#22
0
文件: auth.go 项目: hajimehoshi/otaru
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
}
示例#24
0
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")
}
示例#25
0
//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
}
示例#26
0
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
}
示例#27
0
// 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)
}
示例#28
0
文件: oauth.go 项目: mastef/itembase
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
}
示例#29
0
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()
	}
}
示例#30
0
// 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
}