Jan 082012
 

This is the second part of a three part series on how to embed a Google Calendar into a web page and use it to accept online bookings/appointments from other online users.

The Series:

  1. Part 1: Setting up Google Calendar
  2. Part 2: OAuth2 and Configuring Your ‘Application’ With Google <- You Are Here
  3. Part 3: A Sample Web Page For Bookings

Background

This was by far the hardest part of the whole exercise. I had worked with version 1 of the Google API for PHP a few years back. This allowed you to code your username and password into your script, and it would handle authentication for your application. Now that we are on to version 3 of the API, that method is no longer available. Instead OAuth2 is used for authentication and token management.

I downloaded code samples, and went about building my application, however, I quickly realized that the OAuth2 code samples are designed to allow you to interact with a visitors calendar. In the case of taking online bookings, I need to work with a single calendar, namely my calendar, not theirs.

After a lot of trial and error, and then reading, I realized that it could be done, and relied on what is called a ‘Refresh Token’ in OAuth2. This token allows you to get a new valid authentication token when the initial grant from your end user expires. Since the refresh token doesn’t expire, you can always use it to get a new authentication token, and therefore people can continue to use your application after you have initially configured it. I spent a while trying to implement it myself with no success, but then I came across this page: http://www.ericnagel.com/how-to-tips/google-affiliate-network-api.html This explains in some detail how to configure the application and token. It is written for the Google Affiliate Network API, but I made a few tweaks to make it work for Calendar. I will now take you through the steps of setting up your application with Google, and generating your Refresh Token.

Create Your Application

Log into your Google Account, and then visit https://code.google.com/apis/console/. This will take you to a page that invites you to create a project with the Google API. Click on Create project….

You are now asked to activate the services you wish to use. Click the button next to Calendar API to enable the calendar. You will be redirected to a page with a Terms of Service. Read and accept this.

Now click on API Access. Here we will configure the IDs needed for your application to authenticate with Google. Click on Create an OAuth2 client ID…. You will be offered to create Branding Information. You should add your project/product name. The rest won’t be necessary as you will not be asking users directly for access to their resources, but you can complete it if you like.

Then click Next. Here you will want to select Installed application. Click Create client ID.

You will be taken back to the API Access screen, with your new Client ID and Client secret. You will need this information to generate your Refresh Token, and to configure your application.

This page will also have your API key for ‘Simple API Access’. You will also need this API Key for your final calendar application.

Get Your Application Information

Now that you have your application information, it is time to generate your refresh token. I’ve modified the script available from http://www.ericnagel.com/how-to-tips/google-affiliate-network-api.html to just get us our refresh token for our calendar application. Here is the code for the script. Download this and save it as oauth-setup.php:

<?php
$cScope         =   'https://www.googleapis.com/auth/calendar';
$cClientID      =   '';
$cClientSecret  =   '';
$cRedirectURI   =   'urn:ietf:wg:oauth:2.0:oob';
 
$cAuthCode      =   '';

if (empty($cAuthCode)) {
    $rsParams = array(
                        'response_type' =>   'code',
                        'client_id'     =>   $cClientID,
                        'redirect_uri'  =>   $cRedirectURI,
                        'scope'         =>   $cScope
                        );
    $cOauthURL = 'https://accounts.google.com/o/oauth2/auth?' . http_build_query($rsParams);
    echo("Go to\n$cOauthURL\nand enter the given value into this script under \$cAuthCode\n");
    exit();
} // ends if (empty($cAuthCode))
elseif (empty($cRefreshToken)) {
    $cTokenURL = 'https://accounts.google.com/o/oauth2/token';
    $rsPostData = array(
                        'code'          =>   $cAuthCode,
                        'client_id'     =>   $cClientID,
                        'client_secret' =>   $cClientSecret,
                        'redirect_uri'  =>   $cRedirectURI,
                        'grant_type'    =>   'authorization_code',
                        );
    $ch = curl_init();
 
    curl_setopt($ch, CURLOPT_URL, $cTokenURL);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $rsPostData);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
    $cTokenReturn = curl_exec($ch);
    $oToken = json_decode($cTokenReturn);
    echo("Here is your Refresh Token for your application.  Do not loose this!\n\n");
    echo("Refresh Token = '" . $oToken->refresh_token . "';\n");
} // ends
?>

Before running this script, you will need to enter your Client ID ($cClientID) and Client Secret ($cClientSecret) as we found on the API page with Google. Once these values are added, run this script from the command line like this: php oauth-setup.php. You should see output like this:

thomas@thomas-desktop:~/code$ php oauth-setup.php 
Go to

https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=##########################&redirect_uri=###############&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar

and enter the given value into this script under $cAuthCode

Visit the website, grant permission to access your resources, and then copy the code on this page. This is your auth code, and is normally good for 3600 seconds or so.

Enter this code into the oauth-setup.php script in the $cAuthCode variable. Then run the script again: php oauth-setup.php. You should see output like this:

thomas@thomas-desktop:~/code$ php oauth-setup.php 
Here is your Refresh Token for your application.  Do not loose this!

Refresh Token = '#####################################';

Now, copy down the Refresh Token and save it for later. You will need it to make subsequent requests to Google to get a valid Auth Code for a transaction.

Stay tuned for Part 3 of the tutorial, which will use the above information to make calendar requests to Google. And allow us to create a web application that uses Google Calendar as a backend for a scheduling application.

  27 Responses to “Part 2: OAuth2 and Configuring Your ‘Application’ With Google”

  1. [...] Part 2: OAuth2 and Configuring Your ‘Application’ With Google [...]

  2. Thanks for linking back to my website… I’m surprised how complicated Google made this process with OAuth.

    Did you try using the Simple API w/ a secret key? I had that working for Picasa, but not for the Google Affiliate Network, which was the service I was interfacing with.

  3. Can’t wait for part 3. Thanks for creating and sharing this tutorial. :)

  4. Hello Eric,
    I did try using the simple API key, but I couldn’t get that working. I think API + Key was doable for the Calendar API V2, but not for V3 when they introduced OAuth2. Although, you figured if they forced everyone to move to a new model, they would have better examples on how to use it for the same purpose.

    Thanks for your post though….I was searching for hours before I ran across your post which gave my the key points I needed to figure it all out. :)

  5. [...] Part 2: OAuth2 and Configuring Your ‘Application’ With Google [...]

  6. Thanks for the post. Do you have any idea why my Refresh Token comes back blank? I tried everything including creating a new app and and reset the private keys but no luck..
    Not sure why OAuth has to be so complicated..

  7. Hummm, not something I’ve run across yet. Do any steps of the process work? For example, are you able to get your auth code?

  8. Thanks for the post. Do you have any idea why my Refresh Token comes back blank? I tried everything including creating a new app and and reset the private keys but no luck..
    Not sure why OAuth has to be so complicated..i am getting my auth code correctly…

  9. My Refresh Token was blank also.

    If your Refresh Token is blank… go back to google api console to “Reset client secret…” go through the steps again to reset the cAuthCode value. Instead of running the script a second time in CLI (at the command line)… just go to the script using your browser. Such as http://www.example.com/path/to/the/script/oauth-setup.php

    In the browser you should see the google server response…
    There’s your Refresh Token.. Don’t loose it!

    If you recieve a { “error” : “invalid_grant” } response… start all over again. Reset client secret, etc.

    hope this helps…

  10. You *BLEEPING* wonderful man. You are making my day right now with this article. Google wants to drive us all to insanity.

  11. I also get back a blank Refresh Token no matter what I change. I must be missing something or Google changed something again. It should not be this difficult.

  12. I had a question on Stack Overflow about this (SO Question) and the answer pointed me to this post. However, just recently someone posted a new answer to the question and mentioned that Google now has some docs on server to server authentication. I have not tried it out yet though.

  13. THANK YOU THANK YOU!!!!! This is very helpful. I’ve been working on this for days to no avail.

  14. Hello cornmaster. Any fix with regards to the blank refresh token? I still can’t retrieve it.

  15. Call to undefined function     curl_setopt() in /var/www/grand_taj/application/controllers/oauth-setup.php on line 30
    And the line 30 is : curl_setopt($ch, CURLOPT_URL, $cTokenURL);

  16. Hi, first of this is great, thank you. I am having trouble getting a token as i get Error: redirect_uri_mismatch and I am trying to run this locally as I just want to display my calendar on my server in a certain way. Thanks in advance

  17. It’s blank for me too!

  18. excellent tutorial, but i had this problem with the refresh token:

    Trying to get property of non-object in ….\oauth-setup.php on line 39

    dou you know where is the problem and how can i fixed it?

    thanks!

  19. I would guess that there was a problem with the call to Google and the json returned couldn’t be parsed into an object.

    Without a look at the script I won’t be able to tell you much more. Although a number of folks have had similar problems. Did you try the solution posted by Jerry above?

  20. I have tried this and I keep getting the error below when I run the script for the second time.

    I have tried Jerry’s comment also – but it also gives the same response (just styled nicer than the cli obviously)

    Any help would be excellent.

    Thanks for the tutorial by the way :)


    Here is your Refresh Token for your application. Do not loose this!

    PHP Notice: Trying to get property of non-object in C:\wamp\www\site\codeIgniter_application\views\temp\oauth_setup.php on line 40
    PHP Stack trace:
    PHP 1. {main}() C:\wamp\www\site\codeIgniter_applicatio
    n\views\temp\oauth_setup.php:0

    Notice: Trying to get property of non-object in C:\wamp\www\site\codeIgniter_application\views\temp\oauth_setup.php on line 40

    Call Stack:
    0.0006 638160 1. {main}() C:\wamp\www\site\code
    Igniter_application\views\temp\oauth_setup.php:0

    Refresh Token = '';

  21. I tried the solution posted by Jerry, but unfortunately it didn’t work :/

  22. Beautifull – going to ppart 3.

    Had “blank/empty token” problem – solve it, thanks to “MiniGig Custom Web Development” from the tutorial listed above

    To fix the empty $cRefreshToken issue you need to enable SSL by adding
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    right before curl_exec($ch);

  23. My refresh token is blank. I tried solution by Bac, but it didn’t help.

    Any suggestions?

  24. Great post, though to get a sandbox project token pair you can use the playground as well: https://developers.google.com/oauthplayground/ you just start here and click through to get your tokens.
    All the best!

  25. For those who had trouble getting a non-blank refresh token to return, I found on another site the fix that worked for me: passing another couple of parameters (approval_prompt and access_type) to the original authorization request in oauth-setup.php. So here’s what the parameters variable would look like from Line 10 of the original code:


    $rsParams = array(
    'response_type' => 'code',
    'client_id' => $cClientID,
    'redirect_uri' => $cRedirectURI,
    'access_type' => 'offline',
    'scope' => $cScope,
    'approval_prompt' => 'force'
    );

  26. Bac, Thank you, you saved me. blank refresh token problem solved

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>