diff --git a/internal/token.go b/internal/token.go index e83ddeef0..3359ca362 100644 --- a/internal/token.go +++ b/internal/token.go @@ -50,6 +50,11 @@ type Token struct { // mechanisms for that TokenSource will not be used. Expiry time.Time + // ExpiresIn is the OAuth2 wire format "expires_in" field, + // which specifies how many seconds later the token expires, + // relative to an unknown time base approximately around "now". + ExpiresIn int64 + // Raw optionally contains extra metadata from the server // when updating a token. Raw interface{} @@ -295,6 +300,7 @@ func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) { expires, _ := strconv.Atoi(e) if expires != 0 { token.Expiry = time.Now().Add(time.Duration(expires) * time.Second) + token.ExpiresIn = int64(expires) } default: var tj tokenJSON @@ -312,6 +318,7 @@ func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) { TokenType: tj.TokenType, RefreshToken: tj.RefreshToken, Expiry: tj.expiry(), + ExpiresIn: int64(tj.ExpiresIn), Raw: make(map[string]interface{}), } json.Unmarshal(body, &token.Raw) // no error checks for optional fields diff --git a/token.go b/token.go index 109997d77..ad191b4f3 100644 --- a/token.go +++ b/token.go @@ -163,6 +163,7 @@ func tokenFromInternal(t *internal.Token) *Token { TokenType: t.TokenType, RefreshToken: t.RefreshToken, Expiry: t.Expiry, + ExpiresIn: t.ExpiresIn, raw: t.Raw, } }