在 Angular 中使用 Google One Tap

Mil*_*elo 7 javascript typescript google-identity angular

我想在我的 Angular 11 应用程序中使用 Google One Tap。按照文档,我添加<script async defer src="https://accounts.google.com/gsi/client"></script>到我的 html 中,然后在我的 中使用以下代码app.component.html

<div id="g_id_onload"
    data-client_id="MY_GOOGLE_CLIENT_ID"
    data-callback="handleCredentialResponse",
    data-cancel_on_tap_outside="false">
</div>
Run Code Online (Sandbox Code Playgroud)

弹出窗口工作正常,但我似乎无法登录。如果我handleCredentialResponse在 中创建一个函数app.component.ts,则会收到以下错误:[GSI_LOGGER]: The value of 'callback' is not a function. Configuration ignored.

如果我尝试使用 JavaScript API,Typescript 会抛出以下错误:Property 'accounts' does not exist on type 'typeof google'

我应该怎么做才能在 Angular 中使用 Google One Tap?

may*_*r86 6

当我使用 HTML API 方法时,我遇到了类似的问题,所以我最终使用了JavaScript API

这就是我所做的:

首先,确保安装@types/google-one-tap软件包。

正如您所提到的,我还将脚本导入到我的index.html文件中,如下所示:

<body>
  <script src="https://accounts.google.com/gsi/client" async defer></script>
  <app-root></app-root>
</body>
Run Code Online (Sandbox Code Playgroud)

现在,继续讨论您的主要组件,在我的例子中是app.component.ts,首先导入以下内容:

import { CredentialResponse, PromptMomentNotification } from 'google-one-tap';

然后,您可以将其添加到ngOnInit(). 请务必阅读文档以获取有关onGoogleLibraryLoad事件的更多详细信息:

// @ts-ignore
window.onGoogleLibraryLoad = () => {
  console.log('Google\'s One-tap sign in script loaded!');

  // @ts-ignore
  google.accounts.id.initialize({
    // Ref: https://developers.google.com/identity/gsi/web/reference/js-reference#IdConfiguration
    client_id: 'XXXXXXXX',
    callback: this.handleCredentialResponse.bind(this), // Whatever function you want to trigger...
    auto_select: true,
    cancel_on_tap_outside: false
  });

  // OPTIONAL: In my case I want to redirect the user to an specific path.
  // @ts-ignore
  google.accounts.id.prompt((notification: PromptMomentNotification) => {
    console.log('Google prompt event triggered...');

    if (notification.getDismissedReason() === 'credential_returned') {
      this.ngZone.run(() => {
        this.router.navigate(['myapp/somewhere'], { replaceUrl: true });
        console.log('Welcome back!');
      });
    }
  });
};
Run Code Online (Sandbox Code Playgroud)

然后,该handleCredentialResponse函数是您使用用户凭据处理实际响应的地方。就我而言,我想先对其进行解码。查看此内容以获取有关凭证解码后的外观的更多详细信息: https: //developers.google.com/identity/gsi/web/reference/js-reference#credential

handleCredentialResponse(response: CredentialResponse) {
// Decoding  JWT token...
  let decodedToken: any | null = null;
  try {
    decodedToken = JSON.parse(atob(response?.credential.split('.')[1]));
  } catch (e) {
    console.error('Error while trying to decode token', e);
  }
  console.log('decodedToken', decodedToken);
}
Run Code Online (Sandbox Code Playgroud)