如何通过GrantOfflineAccess

时间:2019-02-22 13:08:03

标签: angular google-calendar-api gapi

我对invalid_grant问题感到震惊。我引用了gapi文档并像这样实现流程,

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);
    });

我从上述实现中获得了访问令牌和response_code,并且能够针对用户创建日历事件。但是一小时后,它给我一个错误,例如“错误:invalid_grant,代码:400”。grantOfflineAccess返回的令牌返回,例如“ 4 / -QA8fj7FyvcPzlVwsapQwyqyKJs0MwkQlNdGhACVgOx3YSP5JamyEplViIx-uSV3JZAHP9A0C”

2 个答案:

答案 0 :(得分:0)

您从响应中获得的代码是服务器应将其交换为)Access Token的一次性代码。请参阅this

不是最好的做法是将refresh_token存储在客户端应用程序上,因为它不安全。如果您只有客户端应用程序,建议您遵循link

希望有帮助。

答案 1 :(得分:0)

正如 Nirav's answer 所提到的,您需要将此一次性令牌交换为随时可以使用的刷新令牌。

您应该使用 google-auth-library 在 Node.js 后端完成此工作流。为此,您将使用身份验证代码来获取刷新令牌。但是,由于这是一个离线工作流程,您还需要验证所提供代码的完整性,如 documentation explains:

const { OAuth2Client } = require('google-auth-library');

/**
* Create a new OAuth2Client, and go through the OAuth2 content
* workflow. Return the refresh token.
*/
function getRefreshToken(code, scope) {
  return new Promise((resolve, reject) => {
    // Create an oAuth client to authorize the API call. Secrets should be 
    // downloaded from the Google Developers Console.
    const oAuth2Client = new OAuth2Client(
      YOUR_CLIENT_ID,
      YOUR_CLIENT_SECRET,
      YOUR_REDIRECT_URL
    );

    // Generate the url that will be used for the consent dialog.
    const authorizeUrl = oAuth2Client.generateAuthUrl({
      access_type: 'offline',
      scope,
    });
    
    // Verify the integrity of the idToken through the authentication 
    // code and use the user information contained in the token
    const { tokens } = await client.getToken(code);
    const ticket = await client.verifyIdToken({
      idToken: tokens.id_token!,
      audience: keys.web.client_secret,
    });
    idInfo = ticket.getPayload();
    return tokens.refresh_token;
  })
}

使用此刷新令牌,您可以随时使用 googleapis 库创建 Google API 客户端。我也在使用这个工作流程来创建事件。对于带有 Node.js 后端的完整工作流,您可能会发现 my gist 很有帮助。