Authentication on google: OAuth2 keeps returning 'invalid_grant'

46,841

Solution 1

You should reuse the access token you get after the first successful authentication. You will get an invalid_grant error if your previous token has not expired yet. Cache it somewhere so you can reuse it.

Solution 2

I was having a similar problem caused by the time on my server being incorrect. Make sure your system clock is synchronised.

Solution 3

Go to your Google API Console ( https://code.google.com/apis/console/ ) and revoke your Client Secret under Client ID for installed applications.

Be sure to also update your code with the new Client Secret

Solution 4

  1. Go to security.google.com
  2. Revoke access
  3. visit the authentication url again
  4. you will now get a new refreshtoken

Solution 5

You'll also receive this error if you mistakenly try to authenticate your ID Token, rather than your Access Token.

So don't be like me - Make sure you pass the correct token into your code!

Share:
46,841
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    I started to configure google calendar on my new application. I almost made an exact copy of the authentication code displayed at google developers ( https://developers.google.com/google-apps/calendar/instantiate ), but i keep getting the following error:

    Error fetching OAuth2 access token, message: 'invalid_grant'

    I'm currently using Fork-CMS ( http://www.fork-cms.com ), a young lightweigth CMS. I correctly configured the config.php file of the google-api-php-client. (client-id, client-secret, redirect-uri, development key,...) and the redirect uri is correctly set on the google api's console. My code looks as follows:

    <?php
    
    /**
    * This is a widget with a calendar implementation.
    *
    * @package       frontend
    * @subpackage    events
    *
    * @author        Michiel Vlaminck <[email protected]>
    */
    class FrontendEventsWidgetCalendar extends FrontendBaseWidget
    {
    
        private $events = array();
        private $authUrl = array();
    
        /**
        * Execute the extra
        *
        * @return    void
        */
        public function execute()
        {      
            // call parent
            parent::execute();
    
            // load template
            $this->loadTemplate();
    
            // get data
            $this->getData();
    
            // parse
            $this->parse();
        }
    
    
        /**
        * Get the data from Google Calendar
        * This method is only executed if the template isn't cached
        *
        * @return    void
        */
        private function getData()
        {
            require_once PATH_LIBRARY . '/external/google-api-php-client/src/apiClient.php';
            require_once PATH_LIBRARY . '/external/google-api-php-client/src/contrib/apiCalendarService.php';
    
            $client = new apiClient();
    
            $service = new apiCalendarService($client);
    
            if (isset($_SESSION['oauth_access_token'])) {
                $client->setAccessToken($_SESSION['oauth_access_token']);
            } else {
                $token = $client->authenticate();
                $_SESSION['oauth_access_token'] = $token;
            }
    
            if ($client->getAccessToken()) {
    
                $calId = FrontendEventsModel::getCalendarId((int) $this->data['id']);
                $calId = $calId[0]['calendar_id'];
    
                $events = $service->events->listEvents($calId);
                $this->events = $events['items'];
    
                $_SESSION['oauth_access_token'] = $client->getAccessToken();
    
            } else {
                $this->authUrl = $client->createAuthUrl();
            }
        }
    
    
        /**
        * Parse
        *
        * @return    void
        */
        private function parse()
        {
            $this->tpl->assign('events', $this->events);
            $this->tpl->assign('authUrl', $this->authUrl);
        }
    }
    
    ?>
    

    When I open this widget-page for the first time, I get directed to google to authenticate the application. When I agree, I get redirected to my application and that's the point where I'm getting:

    apiAuthException » Main
    
    Message Error fetching OAuth2 access token, message: 'invalid_grant'
    File    C:\wamp\www\Officevibes\library/external\google-api-php-client\src\auth\apiOAuth2.php
    Line    105
    Date    Thu, 05 Apr 2012 08:34:47 +0000
    URL http://localhost/calendar?code=4/YPUpFklKvhEeTcMm4moRth3x49oe
    Referring URL   (Unknown)
    Request Method  GET
    User-agent  Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.142 Safari/535.19
    
  • user637563
    user637563 over 10 years
    I think this is no longer true. Using a refresh token, I was able to get an access token, and then another one before the first one expired. (I think this can be seen in OAuth 2.0 Playground also - developers.google.com/oauthplayground ).
  • Rias
    Rias about 9 years
    It was the problem I had as well. I am using a virtual machine to run the API on. directly after wake-up the time isn't synchornized yet.
  • omarojo
    omarojo over 8 years
    Actually.. Im able to use the refresh_token to generate more access_tokens even if the current one hasnt expired. It will just give me a new access_token, and the previous one is still valid. So... Im not sure what you are saying is accurate.
  • janmoesen
    janmoesen over 8 years
    That could very well be. I answered truthfully based on my experience back then. This is an ancient answer in Internet time. Things might have changed in the meanwhile.
  • John
    John about 8 years
    I have tried many solution. This is the last solution I havent tried because I dont understand. What do you mean by "time on server being incorrect"? How to check if the system clock is synchornised?
  • Brett
    Brett about 8 years
    I'd like to know too @John
  • penguin4hire
    penguin4hire about 7 years
    I did the following to sync time on my Ubuntu Linux server which worked for me(assuming you do not have network time protocol(ntp) daemon installed): sudo apt-get install ntp; sudo service ntp stop; sudo ntpdate -s time.nist.gov; sudo service ntp start