I'm working on an eCommerce application in Angular 2 with a node and express api backend. I'm currently working on the social login section where I am using passport-facebook and jwt for authentication. My code concerns revolve around the Angular 2 portion. When a user clicks on the login/register with facebook button it opens a new tab that begins the facebook login flow. That window will then return the jwt to the opener via window.postMessage. The opener then sends the window a success message and the opened window will close. Everything works correctly but it's not very clean, i.e. I had to hack it up to make it work. Ideally I would call my authorization service to handle the facebook login instead of handling everything in my component but inside the event handler for the window.postMessage 'this' no longer references the component, it references the window object so I can't call the service via 'this'. I can't figure out how to get a reference to the component so I can call the service. Does anyone have any suggestions?
Below is my login component in typescript. I can include other code if need be but I don't know that it is needed.
import { Component, OnInit, AfterViewChecked } from '@angular/core';
import { AuthService } from './auth.service';
import { Router } from '@angular/router';
import { ILoginUser } from './loginUser.model';
@Component({
moduleId: module.id,
templateUrl: 'login.component.html',
styleUrls: ['login.component.css']
})
export class LoginComponent implements OnInit {
constructor(private _authService: AuthService, private _router: Router) {
if (window.addEventListener) {
window.addEventListener("message", this.receiveMessage, false);
} else {
(<any>window).attachEvent("onmessage", this.receiveMessage);
}
}
ngOnInit() { }
user: ILoginUser = {
username: "",
password: ""
}
error: boolean = false;
success: boolean = false;
errorMessage: string = "";
redirect: boolean = false;
login() {
this._authService.login(this.user).subscribe(data => {
console.log (data);
if (data.success){
this._router.navigate(['/product']);
} else {
this.error = true,
this.errorMessage = data.message
}
}, errorMsg => {
this.error = true;
this.errorMessage = errorMsg;
});
}
receiveMessage(event: any)
{
if (event.origin !== "http://localhost:3000")
return;
localStorage.setItem("token", event.data.token);
localStorage.setItem("username", event.data.username);
(<any>window).popup.postMessage("success", "http://localhost:3000");
}
ngAfterViewChecked() {
//since we can't call the authservice directly we check to see if a redirect flag is set to true
if (this.redirect) {
this._router.navigate(['/product']);
}
}
authFacebook() {
(<any>window).popup = window.open('http://localhost:3000/api/auth/facebook');
//set the redirect flag to true so when angular checks again we can redirect to the products page
this.redirect = true;
}
}