简体   繁体   English

如何使用最新的谷歌身份服务在 Angular 2+ 中实现谷歌登录

[英]How to Implement Google Sign in in Angular 2+, with the latest google Identity Services

Google has deprecated the old JavaScript implementation for Google Sign. Google 已弃用 Google Sign 的旧 JavaScript 实现。 We should start using the new Identity services.我们应该开始使用新的身份服务。 How to implement this is Angular? Angular怎么实现?

According to Google documentation, it has two ways, one using javascript and the other using HTML.根据 Google 文档,它有两种方式,一种使用 javascript,另一种使用 HTML。

I used HTML to render the button on the page and javascript (typescript to be concise) to import the library into the component and capture the response from Google using a callback function.我使用 HTML 来呈现页面上的按钮,并使用 javascript(简洁的打字稿)将库导入组件并使用回调函数捕获来自 Google 的响应。

so, on our Login Component:所以,在我们的登录组件上:

  • in login.component.html在 login.component.html
    <div id="g_id_onload"
          data-client_id="*********************.apps.googleusercontent.com"
          data-callback="handleCredentialResponse"
          data-auto_prompt="false">
          </div>
    <div class="g_id_signin btn"
            data-type="standard"
            data-size="large"
            data-theme="filled_black"
            data-text="sign_in_with"
            data-shape="rectangular"
            data-logo_alignment="left">
          </div>

please note that the callback function here is "handleCredentialResponse"请注意这里的回调函数是“handleCredentialResponse”

  • in login.component.ts在 login.component.ts
    (function (d, s, id) {
      var js, gjs = d.getElementsByTagName(s)[1];
      if (d.getElementById(id)) { return; }
      js = d.createElement(s); js.id = id;
      js.src = "https://accounts.google.com/gsi/client";
      gjs.parentNode.insertBefore(js, gjs);
    }(document, 'script', 'async defer'));

    (window as any).handleCredentialResponse = (response) => {
      console.log(response);
      if (response && response.credential){
          // handle the response here...
            }
          }, err => {
            console.log(err);
          })
        }
      };

For me, I send response.credential to the back end server to be validated, but you can decode the response on you Angular App if you want, and for this you can use something like jwt-decode .对我来说,我将response.credential发送到后端服务器进行验证,但如果需要,您可以在 Angular App 上解码响应,为此您可以使用类似jwt-decode 的东西。

Also, if you faced a problem using it into your Angular App, you can refer to this answer .此外,如果您在 Angular 应用程序中使用它时遇到问题,您可以参考这个答案

New Client IDs created before July 29th, 2022 can use the older Google Platform Library.在 2022 年 7 月 29 日之前创建的新客户端 ID 可以使用旧版 Google 平台库。 By default, newly created Client IDs are now blocked from using the Platform Library and instead must use the newer Google Identity Services library.默认情况下, 新创建的客户端 ID现在无法使用平台库,而必须使用更新的 Google 身份服务库。 You may choose any value, a descriptive name such as product or plugin name is recommended for easy identification.您可以选择任何值,建议使用描述性名称,例如产品或插件名称,以便于识别。

Example: plugin_name: 'login'.示例: plugin_name: '登录'。

Please Read my article Angular 14 Login with Google using OAuth 2.0 where I explained everything step by step.请阅读我的文章Angular 14 Login with Google using OAuth 2.0 ,我在其中逐步解释了所有内容。

googleAuthSDK() {

    (<any>window)['googleSDKLoaded'] = () => {
      (<any>window)['gapi'].load('auth2', () => {
        this.auth2 = (<any>window)['gapi'].auth2.init({
          client_id: 'YOUR CLIENT ID',
          plugin_name:'login',
          cookiepolicy: 'single_host_origin',
          scope: 'profile email'
        });
        this.callLogin();
      });
    }

We assume that you already have a Google key for this type of service (Google Client ID) so we proceed to integrate the new Google Sign Identity services in an Angular app.我们假设您已经拥有此类服务的 Google 密钥(Google 客户端 ID),因此我们继续将新的 Google Sign Identity 服务集成到 Angular 应用程序中。

  1. As a good practice, we add to our environment file the variable googleClientId with our Google key mentioned above.作为一种好的做法,我们使用上面提到的 Google 密钥将变量 googleClientId 添加到我们的环境文件中。

 export const environment = {... googleClientId: 'YOUR_GOOGLE_CLIENT_ID', };

  1. In the index.html file we add the Google script that will allow us to use this functionality.在 index.html 文件中,我们添加了允许我们使用此功能的 Google 脚本。

 <.doctype html> <html lang="en"> <head>..: </head> <body> <app-root></app-root> <script src="https.//accounts.google.com/gsi/client" async defer></script> </body> </html>

  1. We install the google one tap types package ( @types/google-one-tap ) to help us with the integration (optional).我们安装了谷歌一键式 package ( @types/google-one-tap ) 来帮助我们进行集成(可选)。

  2. In the component where we are going to use this functionality, in the.ts file we declare the google global variable.在我们将要使用此功能的组件中,在 .ts 文件中,我们声明了 google 全局变量。 In the ngAfterViewInit hook we initialise the button and render it by referring to the id we have assigned to the HTML element where the iframe will be injected.在 ngAfterViewInit 钩子中,我们初始化按钮并通过引用我们分配给 HTML 元素的 id 来渲染它,iframe 将被注入该元素。 In the initialisation method, the callback is where we collect the token that Google returns to us when logging in and we use ngZone because the navigation will be triggered outside Angular zone.在初始化方法中,回调是我们收集 Google 在登录时返回给我们的令牌的地方,我们使用 ngZone 因为导航将在 Angular 区域之外触发。

 declare var google: any; import { AfterViewInit, Component, ElementRef, NgZone } from '@angular/core'; import { accounts } from 'google-one-tap'; import { environment } from 'src/environments/environment'; @Component({ selector: 'app-login-page', templateUrl: './login.component.html', styleUrls: ['./login.component.scss'], }) export class LoginPageComponent implements AfterViewInit { constructor(private ngZone: NgZone) {} ngAfterViewInit() { const gAccounts: accounts = google.accounts; gAccounts.id.initialize({ client_id: environment.googleClientId, ux_mode: 'popup', cancel_on_tap_outside: true, callback: ({ credential }) => { this.ngZone.run(() => { this._loginWithGoogle(credential); }); }, }); gAccounts.id.renderButton(document.getElementById('gbtn') as HTMLElement, { size: 'large', width: 320, }); } private _loginWithGoogle(token: string) {... } }

  1. In Index.html, Paste this script tag under the head tag, like below.在 Index.html 中,将此脚本标签粘贴到 head 标签下,如下所示。

 <head> <script src="https://accounts.google.com/gsi/client" async defer> </script> </head>

  1. In the html component, add this below code to show google login button.在 html 组件中,添加以下代码以显示 google 登录按钮。

 <div id="googleButton"></div>

  1. Finally in the ts file, add the below code with your google client ID.最后在 ts 文件中,使用您的 google 客户端 ID 添加以下代码。

 constructor(private ngZone: NgZone) ngAfterViewInit() { google.accounts.id.initialize({ client_id: "", callback: (window as any)['handleCredentialResponse'] = (response: any) => this.ngZone.run(() => { console.log("this response holds the token for the logged in user information",response) }) }); google.accounts.id.renderButton( document.getElementById("googleButton"), { type: "standard", text: "signin_with", theme: "outline", size: "medium", width: "250"} ) }

  1. In the response, you will be getting a token, you have to decode it to get retrieve the logged in user information, you can probably use 'jwt-decode' package to do so.在响应中,您将获得一个令牌,您必须对其进行解码以检索登录的用户信息,您可以使用“jwt-decode”包来执行此操作。

 import jwt_decode from 'jwt-decode'; jwt_decode(response.credential);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM