Invaild Grant issue in Xero OAuth2.0 Refresh token
Asked Answered
T

3

7

I'm using Xero OAuth2.0 APIs, I am refreshing token once token is expired. Xero Documentation I'm storing token in JSON file so i can retrive next time.

Erorr Response:

{
"error": "invalid_grant"
}

Please refer below code i've used

public function getAccessToken($code = null) {
    if(file_exists($this->tokenPath) && isset($code)) {
        $accessToken = $this->getAccessTokenFromAuthCode($code);
    } else if (file_exists($this->tokenPath)) {
        $accessToken = $this->getAccessTokenFromJSON();
        try {
            if (time() > $accessToken->expires) {
                $accessToken = $this->provider->getAccessToken('refresh_token', [
                    'refresh_token' => $accessToken->refresh_token
                ]);
            }
        } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
            //header('Location: ' . $this->getAuthorizationUrl());
        }

    } else if(isset($code)){
        $accessToken = $this->getAccessTokenFromAuthCode($code);
    } else {
        header('Location: ' . $this->getAuthorizationUrl());
    }

    return $accessToken;
}

public function getAccessTokenFromAuthCode($code) {
    return $this->storeAccessTokenToJSON($this->provider->getAccessToken('authorization_code', ['code' => $code]));
}

public function getAccessTokenFromJSON(){

    return json_decode(file_get_contents($this->tokenPath));
}

public function storeAccessTokenToJSON($accessToken){
    file_put_contents($this->tokenPath, json_encode($accessToken));

    return json_decode(file_get_contents($this->tokenPath));
}
Titanesque answered 7/1, 2020 at 6:15 Comment(1)
Check if the configuration you have given in the app matches the configurations you used to generate the initial file.Virus
R
3

The expiration for an access token is 30 minutes. And Unused refresh tokens expire after 60 days. If you don’t refresh your access token within 60 days the user will need to reauthorize your app.

  • If you perform a token refresh successfully you get a new refresh token with the new access token
  • If for whatever reason, you don't receive the response after performing the token refresh you can retry refreshing the old token for a grace period of 30 minutes
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://identity.xero.com/connect/token?=",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => array(
 'XXXXXXXXXXXXX','client_secret' =>
 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYY'),
  CURLOPT_HTTPHEADER => array(
    "grant_type: refresh_token",
    "Content-Type: application/json",
     ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
Runkel answered 15/4, 2020 at 12:40 Comment(0)
O
0

Did you specify the 'offline_access' scope when you got your initial token?

https://developer.xero.com/documentation/guides/oauth2/scopes#offline-access

Orchid answered 1/2, 2022 at 5:53 Comment(1)
Please phrase this as an explained conditional answer, in order to avoid the impression of asking a clarification question instead of answering (for which a comment should be used instead of an answer, compare meta.stackexchange.com/questions/214173/… ). For example like "If your problem is ... then the solution is to .... because .... ."Surfeit
S
-1

Invalid_grant is the standard error response code when a refresh token has expired.

Common token lifetimes are something like: * Access token = 60 minutes * Refresh token = 8 hours

When the refresh token expired you have to get the user to log in again.

Sassan answered 7/1, 2020 at 7:56 Comment(1)
According to the docs, developer.xero.com/documentation/oauth2/auth-flow, "Your app can refresh an access token without user interaction by using a refresh token". This appears to be broken.Byproduct

© 2022 - 2024 — McMap. All rights reserved.