6
votes

I'm trying to add a login/logout to/from google by their guide: https://developers.google.com/identity/sign-in/web/sign-in

But I'm facing some problems.

index.html:

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://apis.google.com/js/platform.js" async defer></script>
  <meta name="google-signin-client_id" content="**my-google-api-key**.apps.googleusercontent.com">
  <script>
    gapi.load('auth2',function () {
      gapi.auth2.init();
    });
  </script>

app.component.html:

<div class="g-signin2" data-onsuccess="onSignIn"></div>
<a href="#" onclick="signOut();">Sign out</a>

app.component.ts:

public onSignIn(googleUser):void {
    var profile = googleUser.getBasicProfile();
    console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
    console.log('Name: ' + profile.getName());
    console.log('Image URL: ' + profile.getImageUrl());
    console.log('Email: ' + profile.getEmail());
  }
  public signOut():void {
    var auth2 = gapi.auth2.getAuthInstance();
    auth2.signOut().then(function () {
      console.log('User signed out.');
    });
  }

Problems:

  1. After logging in succussfully, onSignIn function does not get called so nothing is printed but the signIn is working.
  2. In the signOut function I have error: "Cannot find name 'gapi'." but the signout is working.

Question:

Google tells us not to use the googleUser.getBasicProfile().getId() as the user ID but use the ID Token intead: googleUser.getAuthResponse().id_token.sub. Why?

3
Have you successfully accomplished this? I'm stuck on the same thing... - mrgoos
yes I moved to firebase and there you have easy way to login with google/facebook/.... its so easy. you call login and subscribe to changes to the auth object you recive after logging in. (if it was successfull u get the user details etc). I use firebase for a dabase to replace server side in my application but i think i would use firebase api to login though google even if I wont use it as a dababse. CHECK OUT: angularfire from github and this link: github.com/firebase/angularfire/blob/master/docs/guide/… - Stav Alfi
Cool. Yeah firebase is great but I can't use it in my project. I did find a way though, I will put it as an answer. - mrgoos

3 Answers

14
votes

I solved it by using NgZone. Not sure if it's the best way but it's the best until I'll find another one :)

import { Component, NgZone } from '@angular/core';
......
......
constructor(ngZone: NgZone) {
  window['onSignIn'] = (user) => ngZone.run(() => this.onSignIn(user));
}
......
......
onSignIn(googleUser) {
  //now it gets called
......
}
2
votes

you can simply add your onSignIn method to window to get called, by following code.

constructor() {
    const _self = this;
    window['onSignIn'] = function (user) {
      _self.onSignIn(user);
    };
  }

onSignIn(googleUser) {
 // sign in code
}

may this link help for your last question.

Authenticate with a backend server

they described:

Warning: Do not accept plain user IDs, such as those you can get with the GoogleUser.getId() method, on your backend server. A modified client application can send arbitrary user IDs to your server to impersonate users, so you must instead use verifiable ID tokens to securely get the user IDs of signed-in users on the server side.

2
votes

mrgoos answer helped me, but we can make it cleaner without NGZone:

constructor() {
  window['onSignIn'] = this.onSignIn;
}