Search code examples
node.jsgoogle-apigoogle-calendar-apigoogle-oauthgoogle-api-nodejs-client

Get permissions on user's Google Calendar to use them from server


The requirement:

I have to develop the following feature: user clicks a button on my site and then a Google's dialog is popping-up asking for permissions on his calendar for my application. If the user accepts that - my server application (let's say NodeJS) should be able to read his events any time (not only for 30 days).

Here is what I've tried:

I was following these tutorials (both NodeJS and Browser) https://developers.google.com/calendar/quickstart/nodejs

NodeJS tutorial gives me permissions on my account (while I need the users to give permissions on their accounts).

Browser tutorial pop-ups the dialog and asks for permissions. If user accepts the request, then it ends up with permission on the calendar only for 1 hour (so even if I can use the token from my server it doesn't solve the problem). To check it just try to print the Promise's result from handleAuthClick by modifying it a bit

gapi.auth2.getAuthInstance().signIn().then(res => {console.log(res)});

Look at the expires_in (or expires_at) in the printed result:

{
  "El": "117770076845340691060",
  "Zi": {
    "token_type": "Bearer",
    "access_token": "ya29.Glb...zr8Yx",
    "scope": "https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email openid email profile",
    "login_hint": "AJDLj...WlQ",
    "expires_in": 3600,
    "id_token": "eyJhvGciO...sHxw6HcA",
    "session_state": {
      "extraQueryParams": {
        "authuser": "1"
      }
    },
    "first_issued_at": 1528384733411,
    "expires_at": 1528388333411,
    "idpId": "google"
  },
  "w3": {
    "Eea": "117770076845340691060",
    "ig": "Bryan Gray",
    "ofa": "Bryan",
    "wea": "Gray",
    "Paa": "https://lh3.googleusercontent.com/-zQ8KN1XZtJI/AAAAAAAAAAI/AAAAAAAAAAA/AB...e/s96-c/photo.jpg",
    "U3": "alex@khealth.ai"
  }
}

Solution

  • Access tokens are only usable for an hour you need a refresh token which will allow you to request a new access token when ever you need one. To do that you need to request offline access.

     gapi.signin2.render('glogin', {
                    'class': 'g-signin',
                    redirect_uri: 'postmessage',
                    onsuccess: signInCallback,
                    cookiepolicy: 'single_host_origin',
                    accesstype: 'offline',
                    theme: 'dark'
                });
    

    Code from this sample Google oauth2