为了账号安全,请及时绑定邮箱和手机立即绑定

在 Angular 中使用 Google One Tap

在 Angular 中使用 Google One Tap

繁花不似锦 2024-01-18 16:16:22
我想在我的 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>弹出窗口工作正常,但我似乎无法登录。如果我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?
查看完整描述

4 回答

?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

当我使用 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>

现在,继续讨论您的主要组件,在我的例子中是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!');

      });

    }

  });

};

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

// @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!');

      });

    }

  });

};


查看完整回答
反对 回复 2024-01-18
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

设置模板中的div在ngOnInit中渲染


    `<div id="loginBtn" > </div>`

在您的login.ts中动态注入脚本标签,如下所示


constructor(private _renderer2: Renderer2, @Inject(DOCUMENT) private _document: Document){}


ngAfterViewInit() {

        const script1 = this._renderer2.createElement('script');

        script1.src = `https://accounts.google.com/gsi/client`;

        script1.async = `true`; 

        script1.defer = `true`; 

    this._renderer2.appendChild(this._document.body, script1);

  }


ngOnInit(): void { 

    // @ts-ignore

    window.onGoogleLibraryLoad = () => {  

      // @ts-ignore

      google.accounts.id.initialize({

        client_id: '335422918527-fd2d9vpim8fpvbcgbv19aiv98hjmo7c5.apps.googleusercontent.com',

        callback: this.googleResponse.bind(this),

        auto_select: false,

        cancel_on_tap_outside: true,  

      })

      // @ts-ignore

      google.accounts!.id.renderButton( document!.getElementById('loginBtn')!, { theme: 'outline', size: 'large', width: 200 } )

      // @ts-ignore

      google.accounts.id.prompt(); 

    }

  }



async googleResponse(response: google.CredentialResponse) { 

        // your logic goes here

}


查看完整回答
反对 回复 2024-01-18
?
PIPIONE

TA贡献1829条经验 获得超9个赞

我在将函数添加到角度分量时也遇到了同样的问题。然后我找到了一个解决方案,通过添加 JS 函数,appComponent如下所示:


(window as any).handleCredentialResponse = (response) => {

      /* your code here for handling response.credential */

}


查看完整回答
反对 回复 2024-01-18
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

Google One Tap js 库尝试在全局范围内查找callback,但找不到它,因为您的callback函数的范围位于应用程序内部的某个位置,因此您可以将回调附加到 window, like window.callback = function(data) {...}。另外,由于您将其附加到窗口,因此最好为该函数指定一个不太通用的名称。



查看完整回答
反对 回复 2024-01-18
  • 4 回答
  • 0 关注
  • 163 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信