diff --git a/backend/box/box.go b/backend/box/box.go index e932b0762..e69491871 100644 --- a/backend/box/box.go +++ b/backend/box/box.go @@ -185,7 +185,9 @@ func refreshJWTToken(ctx context.Context, jsonFile string, boxSubType string, na signingHeaders := getSigningHeaders(boxConfig) queryParams := getQueryParams(boxConfig) client := fshttp.NewClient(ctx) - err = jwtutil.Config("box", name, tokenURL, *claims, signingHeaders, queryParams, privateKey, m, client) + //When using OAuth2.0 with JWT Box appears to expire their tokens earlier than expected. + //To counter this, we manually set the token to expire 2 minutes earlier than expected + err = jwtutil.Config("box", name, tokenURL, *claims, signingHeaders, queryParams, privateKey, m, client, time.Duration(2*time.Minute)) return err } diff --git a/lib/jwtutil/jwtutil.go b/lib/jwtutil/jwtutil.go index e5f0dbd8e..9fa14becc 100644 --- a/lib/jwtutil/jwtutil.go +++ b/lib/jwtutil/jwtutil.go @@ -32,7 +32,7 @@ func RandomHex(n int) (string, error) { } // Config configures rclone using JWT -func Config(id, name, url string, claims jwt.Claims, headerParams map[string]interface{}, queryParams map[string]string, privateKey *rsa.PrivateKey, m configmap.Mapper, client *http.Client) (err error) { +func Config(id, name, url string, claims jwt.Claims, headerParams map[string]interface{}, queryParams map[string]string, privateKey *rsa.PrivateKey, m configmap.Mapper, client *http.Client, earlyExpire time.Duration) (err error) { jwtToken := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) for key, value := range headerParams { jwtToken.Header[key] = value @@ -93,7 +93,7 @@ func Config(id, name, url string, claims jwt.Claims, headerParams map[string]int } e := result.ExpiresIn if e != 0 { - token.Expiry = time.Now().Add(time.Duration(e) * time.Second) + token.Expiry = time.Now().Add(time.Duration(e) * time.Second - earlyExpire) } return oauthutil.PutToken(name, m, token, true) } diff --git a/lib/oauthutil/oauthutil.go b/lib/oauthutil/oauthutil.go index d3562e41a..d8e97c94f 100644 --- a/lib/oauthutil/oauthutil.go +++ b/lib/oauthutil/oauthutil.go @@ -18,7 +18,6 @@ import ( "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" - "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/fshttp" "github.com/rclone/rclone/lib/random" "github.com/skratchdot/open-golang/open" @@ -267,9 +266,10 @@ func (ts *TokenSource) Token() (*oauth2.Token, error) { if ts.reReadToken() { changed = true } else if ts.token.RefreshToken == "" { - return nil, fserrors.FatalError( - fmt.Errorf("token expired and there's no refresh token - manually refresh with \"rclone config reconnect %s:\"", ts.name), - ) + //Box authentication OAuth2.0 with JWT does not provide refresh tokens + //return nil, fserrors.FatalError( + // fmt.Errorf("token expired and there's no refresh token - manually refresh with \"rclone config reconnect %s:\"", ts.name), + //) } }