bearer/bearer.go
func (b *Bearer) Token() (*oauth2.Token, error) {
	var err error

	claims := make(map[string]interface{}, len(b.claims))
	for k, val := range b.claims {
		claims[k] = val
	}

	now := time.Now()
	n := json.Number(strconv.FormatInt(now.Unix(), 10))

	// add expiration
	if b.addExpiration {
		claims["exp"] = json.Number(strconv.FormatInt(now.Add(b.expiresIn).Unix(), 10))
	}

	// add issued at
	if b.addIssuedAt {
		claims["iat"] = n
	}

	// add not before
	if b.addNotBefore {
		claims["nbf"] = n
	}

	// encode token
	buf, err := b.signer.Encode(claims)
	if err != nil {
		return nil, fmt.Errorf("jwt/bearer: could not encode claims: %v", err)
	}

	// build client
	client := oauth2.NewClient(b.context, nil)
	client.Transport = b.transport

	// create values
	v := url.Values{}
	v.Set("grant_type", GrantType)
	v.Set("assertion", string(buf))

	// do assertion
	res, err := client.PostForm(b.tokenURL, v)
	if err != nil {
		return nil, fmt.Errorf("jwt/bearer: cannot do token assertion: %v", err)
	}
	defer res.Body.Close()

	// read response
	body, err := ioutil.ReadAll(io.LimitReader(res.Body, 1<<20))
	if err != nil {
		return nil, fmt.Errorf("jwt/bearer: cannot fetch token: %v", err)
	}

	// check status code
	if c := res.StatusCode; c < 200 || c > 299 {
		return nil, fmt.Errorf("jwt/bearer: cannot fetch token: %s (%d): %s", res.Status, res.StatusCode, string(body))
	}

	// decode body
	var tv struct {
		AccessToken string `json:"access_token"`
		TokenType   string `json:"token_type"`
		IDToken     string `json:"id_token"`
		ExpiresIn   int64  `json:"expires_in"`
	}

	// unmarhsal returned token
	err = json.Unmarshal(body, &tv)
	if err != nil {
		return nil, fmt.Errorf("jwt/bearer: cannot fetch token: %v", err)
	}

	ret := &oauth2.Token{
		AccessToken: tv.AccessToken,
		TokenType:   tv.TokenType,
	}

	// check passed expiration time
	if secs := tv.ExpiresIn; secs > 0 {
		ret.Expiry = time.Now().Add(time.Duration(secs) * time.Second)
	}

	if tv.IDToken != "" {
		var e struct {
			Expiration int64 `json:"exp"`
		}

		// decode returned id_token to get expiration
		err = b.signer.Decode([]byte(tv.IDToken), &e)
		if err != nil {
			return nil, fmt.Errorf("jwt/bearer: could not decode id_token: %v", err)
		}

		ret.Expiry = time.Unix(e.Expiration, 0)
	}

	return ret, nil
}
func (b *Bearer) Token() (*oauth2.Token, error) {
	var err error

	claims := make(map[string]interface{}, len(b.claims))
	for k, val := range b.claims {
		claims[k] = val
	}

	now := time.Now()
	n := json.Number(strconv.FormatInt(now.Unix(), 10))

	// add expiration
	if b.addExpiration {
		claims["exp"] = json.Number(strconv.FormatInt(now.Add(b.expiresIn).Unix(), 10))
	}

	// add issued at
	if b.addIssuedAt {
		claims["iat"] = n
	}

	// add not before
	if b.addNotBefore {
		claims["nbf"] = n
	}

	// encode token
	buf, err := b.signer.Encode(claims)
	if err != nil {
		return nil, fmt.Errorf("jwt/bearer: could not encode claims: %v", err)
	}

	// build client
	client := oauth2.NewClient(b.context, nil)
	client.Transport = b.transport

	// create values
	v := url.Values{}
	v.Set("grant_type", GrantType)
	v.Set("assertion", string(buf))

	// do assertion
	res, err := client.PostForm(b.tokenURL, v)
	if err != nil {
		return nil, fmt.Errorf("jwt/bearer: cannot do token assertion: %v", err)
	}
	defer res.Body.Close()

	// read response
	body, err := ioutil.ReadAll(io.LimitReader(res.Body, 1<<20))
	if err != nil {
		return nil, fmt.Errorf("jwt/bearer: cannot fetch token: %v", err)
	}

	// check status code
	if c := res.StatusCode; c < 200 || c > 299 {
		return nil, fmt.Errorf("jwt/bearer: cannot fetch token: %s (%d): %s", res.Status, res.StatusCode, string(body))
	}

	// decode body
	var tv struct {
		AccessToken string `json:"access_token"`
		TokenType   string `json:"token_type"`
		IDToken     string `json:"id_token"`
		ExpiresIn   int64  `json:"expires_in"`
	}

	// unmarhsal returned token
	err = json.Unmarshal(body, &tv)
	if err != nil {
		return nil, fmt.Errorf("jwt/bearer: cannot fetch token: %v", err)
	}

	ret := &oauth2.Token{
		AccessToken: tv.AccessToken,
		TokenType:   tv.TokenType,
	}

	// check passed expiration time
	if secs := tv.ExpiresIn; secs > 0 {
		ret.Expiry = time.Now().Add(time.Duration(secs) * time.Second)
	}

	if tv.IDToken != "" {
		var e struct {
			Expiration int64 `json:"exp"`
		}

		// decode returned id_token to get expiration
		err = b.signer.Decode([]byte(tv.IDToken), &e)
		if err != nil {
			return nil, fmt.Errorf("jwt/bearer: could not decode id_token: %v", err)
		}

		ret.Expiry = time.Unix(e.Expiration, 0)
	}

	return ret, nil
}
// Token satisfies the oauth2.TokenSource interface.