I am trying to implement google sign-in functionality in my angular app. I have used two packages here @abacritt/angularx-social-login and angular-oauth2-oidc.
I have created a custom provider called google-authentication.service.ts same as from this repository Link. With this approach after a successful sign-in the dialog is not closed and also I am not able to get the logged-in user details.
Question: Please suggest a way to close the dialog after a successful sign-in and get the logged-in user credentials
google-authentication.service.ts:
@Injectable()
export class GoogleAuthenticationService implements LoginProvider {
constructor(private readonly _oAuthService: OAuthService) {
this.createConfiguration();
}
private readonly _tokenReceived$ = this._oAuthService.events.pipe(
filter((e) => e.type === 'token_received'),
map(() => true as const)
);
private createConfiguration(): void {
let redirectUri = window.location.origin + window.location.pathname;
if (redirectUri.endsWith('/')) {
redirectUri = redirectUri.substring(0, redirectUri.length - 1);
}
this._oAuthService.configure({
issuer: 'https://accounts.google.com',
strictDiscoveryDocumentValidation: false,
redirectUri,
silentRefreshRedirectUri: redirectUri,
useSilentRefresh: true,
clientId: environment.googleClientId,
scope: 'openid profile email'
});
}
async initialize(autoLogin?: boolean): Promise<void> {
await this._oAuthService.loadDiscoveryDocument();
if (autoLogin) {
await this._oAuthService.tryLoginImplicitFlow();
}
}
async signIn(): Promise<SocialUser> {
const tokenReceivedPromise = firstValueFrom(this._tokenReceived$);
await this._oAuthService.initImplicitFlowInPopup();
await tokenReceivedPromise;
return this.createUser(this._oAuthService.getIdToken());
}
async getLoginStatus(): Promise<SocialUser> {
if (this._oAuthService.hasValidIdToken()) {
return this.createUser(this._oAuthService.getIdToken());
} else {
throw `No user is currently logged in`;
}
}
async signOut(revoke?: boolean): Promise<void> {
if (revoke) {
this._oAuthService.revokeTokenAndLogout(true, true);
} else {
this._oAuthService.logOut(true);
}
}
private createUser(idToken: string): SocialUser {
const user = new SocialUser();
const payload = JSON.parse(window.atob(idToken.split('.')[1]));
user.idToken = idToken;
user.id = payload.sub;
user.name = payload.name;
user.email = payload.email;
user.photoUrl = payload.picture;
user.firstName = payload['given_name'];
user.lastName = payload['family_name'];
return user;
}
}
Login-component.ts
ngOnInit(): void {
this._googleAuthService.initialize();
}
signUpWithGoogle(event: Event): void {
this._googleAuthService
.signIn()
.then((user) => {
//not showing anything in console
console.log(user);
})
.catch((error) => {
console.log(error);
});
}
It's work for me in this way. According to the new documentation of Google (https://developers.google.com/identity/gsi/web/guides/overview), you should follow next steps:
Create a google app in google cloud console platform and generate a client id.
Load the client library. Add this script "
<script src="https://accounts.google.com/gsi/client" async defer>" between the<head></head>tags of your index.html file of Angular project.Add this code on ngOnInit() function in the component that you would like to have "Sign in with Google button."
Let me know if you have any issues.