I have been trying to implement sign in with Google in angular 2 in a separate login component. I am unable to implement it with the documentation available in Google https://developers.google.com/identity/sign-in/web/sign-in
Google sign in does work when I declare my script tags and google callback function inside my index.html file. But I require a separate component to be able to render the sign in with google button and receive the callback in it to further process the access token which is received for a user
Add this line in your app index.html
file
<script src="https://apis.google.com/js/platform.js" async defer></script>
declare const gapi: any;
public auth2: any;
public googleInit() {
gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
scope: 'profile email'
});
this.attachSignin(document.getElementById('googleBtn'));
});
}
public attachSignin(element) {
this.auth2.attachClickHandler(element, {},
(googleUser) => {
let profile = googleUser.getBasicProfile();
console.log('Token || ' + googleUser.getAuthResponse().id_token);
console.log('ID: ' + profile.getId());
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail());
//YOUR CODE HERE
}, (error) => {
alert(JSON.stringify(error, undefined, 2));
});
}
ngAfterViewInit(){
this.googleInit();
}
<button id="googleBtn">Google</button>
View the demo on Plunker
In the index.html file of your app you need to add this in the <head>
section:
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
You need to add gapi & gapi.auth2 to your typings:
npm install --save @types/gapi.auth2
npm install --save @types/gapi
(see this borysn's question to understand this a little better).
This is the file of my component, here you need to use the ngAfterViewInit()
to use the gapi an get the auth. And you can follow the implementation here developers.google...sign-in/web/build-button
As an example, this is my template:
<div id="my-signin2"></div>
and sign in function:
ngAfterViewInit() {
gapi.signin2.render('my-signin2', {
'scope': 'profile email',
'width': 240,
'height': 50,
'longtitle': true,
'theme': 'light',
'onsuccess': param => this.onSignIn(param)
});
}
public onSignIn(googleUser) {
var user : User = new User();
((u, p) => {
u.id = p.getId();
u.name = p.getName();
u.email = p.getEmail();
u.imageUrl = p.getImageUrl();
u.givenName = p.getGivenName();
u.familyName = p.getFamilyName();
})(user, googleUser.getBasicProfile());
((u, r) => {
u.token = r.id_token;
})(user, googleUser.getAuthResponse());
user.save();
this.goHome();
};
UPDATE: After some time, and taking in consideration the comments, this answer needed a small update.
Lexical scoping with an arrow (=>
) function makes the use of let that = this;
unnecessary.
A cleaner version of Pravesh's example, without the need for the that
scoping work-around, would be:
Index.html
<script src="https://apis.google.com/js/platform.js" async defer></script>
Component.ts
declare const gapi: any;
@Component({
selector: 'google-signin',
template: '<button id="googleBtn">Google Sign-In</button>'
})
export class GoogleSigninComponent implements AfterViewInit {
private clientId:string = 'YOUR_CLIENT_ID.apps.googleusercontent.com';
private scope = [
'profile',
'email',
'https://www.googleapis.com/auth/plus.me',
'https://www.googleapis.com/auth/contacts.readonly',
'https://www.googleapis.com/auth/admin.directory.user.readonly'
].join(' ');
public auth2: any;
public googleInit() {
gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: this.clientId,
cookiepolicy: 'single_host_origin',
scope: this.scope
});
this.attachSignin(this.element.nativeElement.firstChild);
});
}
public attachSignin(element) {
this.auth2.attachClickHandler(element, {},
(googleUser) => {
let profile = googleUser.getBasicProfile();
console.log('Token || ' + googleUser.getAuthResponse().id_token);
console.log('ID: ' + profile.getId());
// ...
}, function (error) {
console.log(JSON.stringify(error, undefined, 2));
});
}
constructor(private element: ElementRef) {
console.log('ElementRef: ', this.element);
}
ngAfterViewInit() {
this.googleInit();
}
}
Template
<div id="googleBtn">Google</div>
Working Plnkr
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With