The LoginExternalProvider component

It's time to hop into Angular. From Solution Explorer, right-click to the /ClientApp/app/components/login/ folder and add a new login.externalproviders.component.ts file with the following content:

import { Component, Inject, OnInit, NgZone, PLATFORM_ID } from "@angular/core";
import { isPlatformBrowser } from '@angular/common';
import { HttpClient } from "@angular/common/http";
import { Router } from "@angular/router";
import { AuthService } from '../../services/auth.service';

declare var window: any;

@Component({
selector: "login-externalproviders",
templateUrl: "./login.externalproviders.component.html"
})

export class LoginExternalProvidersComponent implements OnInit {

externalProviderWindow :any;

constructor(
private http: HttpClient,
private router: Router,
private authService: AuthService,
// inject the local zone
private zone: NgZone,
@Inject(PLATFORM_ID) private platformId: any,
@Inject('BASE_URL') private baseUrl: string) {
}

ngOnInit() {
if (!isPlatformBrowser(this.platformId)) {
return;
}

// close previously opened windows (if any)
this.closePopUpWindow();

// instantiate the externalProviderLogin function
// (if it doesn't exist already)
var self = this;
if (!window.externalProviderLogin) {
window.externalProviderLogin = function (auth:
TokenResponse) {
self.zone.run(() => {
console.log("External Login successful!");
self.authService.setAuth(auth);
self.router.navigate([""]);
});
}
}
}

closePopUpWindow() {
if (this.externalProviderWindow) {
this.externalProviderWindow.close();
}
this.externalProviderWindow = null;
}

callExternalLogin(providerName: string) {
if (!isPlatformBrowser(this.platformId)) {
return;
}

var url = this.baseUrl + "api/Token/ExternalLogin/" +
providerName;
// minimalistic mobile devices support
var w = (screen.width >= 1050) ? 1050 : screen.width;
var h = (screen.height >= 550) ? 550 : screen.height;
var params = "toolbar=yes,scrollbars=yes,resizable=yes,width="
+ w + ", height=" + h;
// close previously opened windows (if any)
this.closePopUpWindow();
this.externalProviderWindow = window.open(url,
"ExternalProvider", params, false);
}
}

Also, here's the login.externalproviders.component.html template file:

<button class="btn btn-sm btn-primary btn-block"
type="submit"
(click)="callExternalLogin('Facebook')">
<span class="glyphicon glyphicon-log-in"></span>
&nbsp;
Login with Facebook
</button>

As we can see, there are many relevant differences between this component and the login.facebook.component.ts that we added when we implemented our implicit flow. Let's try to enumerate them:

  • Instead of relying on an SDK UI button, we're back to a homemade, Angular-driven, Bootstrap-styled button with a generic callExternalLogin event handler method. That's not a surprise, we already know that the explicit flow doesn't require a client-side SDK, since the OAuth2 cycle will be entirely handled with the server-side API endpoints we added to the TokenController early on. The great stuff here is that the event handler, just like these APIs, can act as a common interface with multiple external providers. Theoretically, we can add a Login with Google and/or a Login with Twitter button with the same identical approach.
  • By looking at the callExternalLogin function itself, we can see that it just opens a pop-up window using plain JavaScript with an HTTP request call to the ExternalLogin action method. That's also expected; we knew we had to work around such tasks by ourselves--we addressed it as one of the most relevant flaws of the explicit flow approach. That said, we did what we could to give a decent size to that popup for desktop environments, yet it will hardly work well in mobile browsers; that's definitely an open issue that needs to be fixed.
  • The most relevant stuff in the preceding code lies within the ngOnInit() method; again, we made good use of the Angular zone to include the new externalProviderLogin function that we attached to the main window object instance--along with all the internal references--within the Angular context. This is the cornerstone of the workaround we used to manage the communication between the pop-up window and the main page. The pop-up window--when executing the <SCRIPT> tag received from the TokenController's ExternalLoginCallback response--will look up for that function within its window.opener, which will reference to the window object instance of our Angular app.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.206.225