@@ -325,7 +325,7 @@ func WaitForCallback(clientConfig ClientConfig, serverConfig ServerConfig, hc *h
325
325
326
326
type TokenResponse struct {
327
327
AccessToken string `json:"access_token,omitempty"`
328
- ExpiresIn int64 `json:"expires_in,omitempty"`
328
+ ExpiresIn FlexibleInt64 `json:"expires_in,omitempty"`
329
329
IDToken string `json:"id_token,omitempty"`
330
330
IssuedTokenType string `json:"issued_token_type,omitempty"`
331
331
RefreshToken string `json:"refresh_token,omitempty"`
@@ -334,12 +334,49 @@ type TokenResponse struct {
334
334
AuthorizationDetails []map [string ]interface {} `json:"authorization_details,omitempty"`
335
335
}
336
336
337
+ // FlexibleInt64 is a type that can be unmarshaled from a JSON number or
338
+ // string. This was added to support the `expires_in` field in the token
339
+ // response. Typically it is expressed as a JSON number, but at least
340
+ // login.microsoft.com returns the number as a string.
341
+ type FlexibleInt64 int64
342
+
343
+ func (f * FlexibleInt64 ) UnmarshalJSON (b []byte ) error {
344
+ if len (b ) == 0 {
345
+ return fmt .Errorf ("cannot unmarshal empty int" )
346
+ }
347
+
348
+ // check if we have a number in a string, and parse it if so
349
+ if b [0 ] == '"' {
350
+ var s string
351
+ if err := json .Unmarshal (b , & s ); err != nil {
352
+ return err
353
+ }
354
+
355
+ i , err := strconv .ParseInt (s , 10 , 64 )
356
+ if err != nil {
357
+ return err
358
+ }
359
+
360
+ * f = FlexibleInt64 (i )
361
+ return nil
362
+ }
363
+
364
+ // finally we assume that we have a number that's not wrapped in a string
365
+ var i int64
366
+ if err := json .Unmarshal (b , & i ); err != nil {
367
+ return err
368
+ }
369
+
370
+ * f = FlexibleInt64 (i )
371
+ return nil
372
+ }
373
+
337
374
func NewTokenResponseFromForm (f url.Values ) TokenResponse {
338
375
expiresIn , _ := strconv .ParseInt (f .Get ("expires_in" ), 10 , 64 )
339
376
340
377
return TokenResponse {
341
378
AccessToken : f .Get ("access_token" ),
342
- ExpiresIn : expiresIn ,
379
+ ExpiresIn : FlexibleInt64 ( expiresIn ) ,
343
380
IDToken : f .Get ("id_token" ),
344
381
IssuedTokenType : f .Get ("issued_token_type" ),
345
382
RefreshToken : f .Get ("refresh_token" ),
0 commit comments