Currently, I am delving into Angular and aiming to develop a LinkedIn Login API. To achieve this, I'm utilizing window.open to launch a new window where the user can either accept or decline the authorization. Upon successful acceptance, LinkedIn returns a code which is retrieved using window.addEventListener and event.data. This value is then sent to the parent window using window.opener.postMessage. However, the challenge lies in extracting this value from the addEventListener function to trigger another function with this value.
The component initiating the window popup where the LinkedIn login authorization is accepted or declined
import { Component, OnInit } from '@angular/core';
import { AuthService } from "../../services/auth.service";
import { ActivatedRoute } from "@angular/router";
@Component({
selector: 'app-sign-in',
templateUrl: './sign-in.component.html',
styleUrls: ['./sign-in.component.scss']
})
export class SignInComponent implements OnInit {
private code:string;
private state:string;
constructor(
public auth: AuthService,
public route:ActivatedRoute
) { }
//on initialisation we get the params and send the message to the addEventListener of the parent
ngOnInit() {
//get param of the URI specified in the LinkedIn URL
this.code = this.route.snapshot.queryParamMap.get("code");
this.state = this.route.snapshot.queryParamMap.get("state");
if (this.code !== null){
const params = window.location.search;
if (window.opener) {
//if the params exist then we send the code to the parent window
if (this.state === this.auth.state) {
// send them to the opener window
window.opener.postMessage(this.code);
}
}
} else if (window.opener){
window.opener.postMessage('Authorization canceled');
}
window.close();
}
}
The service where the window.open code is executed to retrieve the value from the child window to the parent window
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
//USER INTERFACE
import { User } from './user.model';
import { auth } from 'firebase/app';
import { AngularFireAuth } from '@angular/fire/auth';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { Observable, of, interval, Subscription } from 'rxjs';
import { switchMap, take } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class AuthService {
user$: Observable<User>;
state: string = '';
clientID: String = '';
keyID: String = '';
urlLinkedin = `https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=${this.clientID}&redirect_uri=http://localhost:4200/authentification/sign-in&scope=r_liteprofile%20r_emailaddress%20w_member_social&state=${this.state}`;
windowAttributes: string = "toolbar=yes,scrollbars=yes,resizable=yes,top=500,left=500,width=520,height=700";
windowTarget: string = "_blank";
codeRecup: string;
constructor(
private afAuth: AngularFireAuth,
private afs: AngularFirestore,
private router: Router,
private http: HttpClient
) {
//METHODS -------------------------------
//LinkedIn ----------------------
linkedinSignin(){
window.open(this.urlLinkedin, this.windowTarget, this.windowAttributes);
window.addEventListener('message',function(event) {
if (event.origin !== "http://localhost:4200")
return;
console.log(event.data);
},false);
}
I aim to fetch event.data and utilize it in another function that will run after the window.addEventListener
linkedinGetToken (){
//I need to retrieve event.data in a new function that will be triggered after the addEventListener
this.codeRecup = event.data;
}
//End LinkedIn ----------------------