google / google-api-javascript-client

Google APIs Client Library for browser JavaScript, aka gapi.
Apache License 2.0
3.19k stars 1.05k forks source link

How to get refresh_token from response_code #509

Open chetanclozio opened 5 years ago

chetanclozio commented 5 years ago

Hi Team, I am struck on on invalid_grant issue. I refer the gapi doc and implement the flow like as, `gapi.client.setApiKey(AuthenticationService.apiKey); var authorisationRequestData = { 'client_id': clientId, 'scope': scopes, 'immediate': immediate, prompt: 'consent', access_type: 'offline', include_granted_scope: true, }

  const authInstance = gapi.auth2.getAuthInstance();
  authInstance.grantOfflineAccess(authorisationRequestData)
    .then((res) => {
      console.log(gapi.auth.getToken());
      var all_token = JSON.stringify(gapi.auth.getToken());
      console.log("Token =" + all_token);
      console.log(res);
      console.log(res.code);
    }).catch(error => {
      console.log(error);
    });`

I get the access token and response_code from above implementation and able to create calendar event against user. But after 1 hour it is giving me error like as, "Error: invalid_grant, code:400". Why the token getting expired? Token return by grantOfflineAccess like as "4/-QA8fj7FyvcPzlVwsapQwyqyKJs0MwkQlNdGhACVgOx3YSP5JamyEplViIx-uSV3JeAHrp9n0RZC0FMSX7IwAQk"

chetanclozio commented 5 years ago

@TMSCH @grant Will you guy's please help me out on this?

SatoshiOoO commented 5 years ago

You are using the access token which is only good for 1 hour. To my understanding you need to use the response_code to exchange for a refresh token, which is usually done at your server side.

I haven't done this before but here is what I found on Google Developers https://developers.google.com/identity/protocols/OAuth2WebServer#exchange-authorization-code

grant commented 5 years ago

Hi, Please see this thread for more info: https://stackoverflow.com/a/24468307/1233286

And the RFC spec for implicit grant flows: https://tools.ietf.org/html/rfc6749#section-4.2

4.2. Implicit Grant

The implicit grant type is used to obtain access tokens (it does not support the issuance of refresh tokens) and is optimized for public clients known to operate a particular redirection URI. These clients are typically implemented in a browser using a scripting language such as JavaScript.

Since this is a redirection-based flow, the client must be capable of interacting with the resource owner's user-agent (typically a web browser) and capable of receiving incoming requests (via redirection) from the authorization server.

Unlike the authorization code grant type, in which the client makes separate requests for authorization and for an access token, the client receives the access token as the result of the authorization request.

The implicit grant type does not include client authentication, and relies on the presence of the resource owner and the registration of the redirection URI. Because the access token is encoded into the redirection URI, it may be exposed to the resource owner and other applications residing on the same device.

chetanclozio commented 5 years ago

@grant How can we get access token and refresh token from the response_code return by grantOfflineAccess() method? possible for you to share the token api link?

gpashis commented 4 years ago

@grant @TMSCH Is this possible to get new access token using gapi.client or any other suggestions would be great.

chetanclozio commented 4 years ago

@gpashis Hi, You need to call external Api for getting the access token. You can use below code as reference for getting access token, Code is return in Node JS. const getRefreshTokenFromGoogleServices = (authCode) => { return new Promise((resolve, reject) => { var jsonRequest = { "client_id": yourClient_id, "client_secret": yourClient_secret, "code": authCode, "grant_type": "authorization_code", "redirect_uri": "postmessage" } console.log(jsonRequest) request({ url: "https://accounts.google.com/o/oauth2/token", method: 'POST', headers: [ { name: 'Content-Type', value: 'application/json' } ], body: jsonRequest, json: true }, function (error, res) { if (error) { // console.error(err); // return reject(err); return reject(error) } else if (res.statusCode === 200) { return resolve(res.body) // return access token valid for 3 months } else { // return reject(res); return reject(res) } }) }) }

gpashis commented 4 years ago

@chetanclozio Thanks for the quick support. I will definitely give this a try.