Corey
Corey

Reputation: 797

Can you reuse a Google service account access token?

Using the Google API PHP Client with a service account, it returns an array like the following:

array (size=3)
  'access_token' => string '...TOKEN...' (length=127)
  'token_type' => string 'Bearer' (length=6)
  'expires_in' => int 3600

Is it best practice to generate a new token every page request? It seems wasteful to do so when each token is valid for one hour. But since the token does not include a created value or a token_id value, the builtin isAccessTokenExpired() method will always return true, meaning it is always expired.

I see several options for reusing the same token:

Option 1: When token is created via fetchAccessTokenWithAssertion(), I can manually add a created value to the token array with time() as its value. Then save that to session/database so later when isAccessTokenExpired is called it will have that field to verify.

Option 2: Save token to session/database along with the timestamp the token will expire (time() + $token['expires_in']), and then on subsequent views I can do my own calculations to verify that the token is still in a valid time period. This seems a bit weird too though as I can't be fully sure that Google has not revoked the token or anything funny like that.

Option 3: Call a method that uses the access token and checks its response. If the call succeeded then the access token must be good still, if not then I can go ahead and ask for a new one. But what method could I call? One that would only need the most basic permissions would be good.

Thank you.

Upvotes: 0

Views: 1272

Answers (1)

Sammitch
Sammitch

Reputation: 32252

You can request a new token each time, but it's needless overhead and I believe it can eat into your API call quota as well.

I basically do #2, but I also subtract 10 seconds off of the expires_in just to be certain I don't have a request made with a just-expired token. TBH there's no reason that Google would revoke an individual token that wouldn't result in full revocation of all access, that's kind of why their token lifetime is so short to begin with.

I don't use the official API client, but the Cliff's Notes version of my logic is:

class Token {
    public function __construct($info) {
        $this->token    = $info['access_token'];
        $this->type     = $info['token_type'];
        $this->expiry   = time() + $info['expires_in'] - 10;
    }

    public function isValid() {
        return ($this->validFor()) > 0;
    }

    public function validFor() {
        return $this->expiry - time();
    }
}

class TokenFactory implements TokenFactoryInterface {
    public function token($force_new=false) {
        if( $force_new || !isset($this->token) || !$this->token->isValid() ) {
            $this->token = $this->newToken();
        }

        return $this->token;
    }
}

Upvotes: 1

Related Questions