簡體   English   中英

如何將HashLocationStrategy與Auth0 Lock小部件一起用於用戶登錄

[英]How to use the HashLocationStrategy with the Auth0 Lock widget for user login

更新后Auth0登錄樣品使用HashLocationStrategyapp.module.ts

import { LocationStrategy, HashLocationStrategy } from '@angular/common';
// (...)
@NgModule({
  providers: [
    {provide: LocationStrategy, useClass: HashLocationStrategy},
    appRoutingProviders,
    AUTH_PROVIDERS
  ],  
//(...)

Auth0 Lock經過authenticated事件不再被引發:

import { Injectable } from '@angular/core';
import { tokenNotExpired } from 'angular2-jwt';

// Avoid name not found warnings
declare var Auth0Lock: any;

@Injectable()
export class Auth0Service {

  // Configure Auth0
  lock = new Auth0Lock('I21EAjbbpf...', '....au.auth0.com', {});

  constructor() {
    // Add callback for lock `authenticated` event
    this.lock.on("authenticated", (authResult) => {
      // Use the token in authResult to getProfile() and save it to localStorage
      this.lock.getProfile(authResult.idToken, function(error, profile) {
        if (error) {
          // Handle error
          return;
        }

        localStorage.setItem('id_token', authResult.idToken);
        localStorage.setItem('profile', JSON.stringify(profile));
      });
    });    
  }
// (...)

您遇到此問題的原因是因為Angular 2路由器將在路由導航時自動清除URL,導致Auth0 Lock永遠不會看到驗證用戶所需的數據 從GitHub來看,這種行為並不總是這樣,但它是現在的行為。 請參閱RC2路由器在匹配路由后從路徑中剝離額外的參數導航不應保留查詢參數和片段以用於某些背景。

執行登錄后,Auth0將請求您的瀏覽器導航到類似於此的URL:

http://example.com/#access_token=RENH3twuqx&id_token=eyJ0.epcOidRwc.Qdx3ac&token_type=Bearer

此URL包含Lock識別用戶已通過身份驗證的所有必要信息,但是, 前面提到的Angular路由器行為意味着在Lock有機會處理此信息之前,URL片段中包含的身份驗證數據將被剝離,網址為( http://example.com/#/ )。 發生這種情況是因為您很可能已配置匹配任何URL的catch-all路由。

假設您配置了以下路由:

const appRoutes: Routes = [
  { path: '', component: HomeComponent },
  { path: '**', redirectTo: '' }
];

免責聲明 :下面顯示的第一個解決方案是作為一個解決方案提供的,證明了Angular 2.0.0 ,與Lock 10.2一起使用的Angular路由器3.0.0的功能。 從那時起,似乎路由器和/或Lock遭受了更改,導致初始解決方法失敗。 我提供了第二種解決方法,它似乎適用於Angular 2.4.1 ,Angular router 3.4.1和Lock 10.7


解決方法#1 - (angular/core@2.0.0,angular/router@3.0.0,lock@10.2)

嘗試繞過此默認行為的一種可能方法是執行以下步驟:

  1. 向處理身份驗證回調請求的路由添加激活防護,以便在當前URL看起來像是登錄結果時不允許路由激活(例如,在其片段中包含access_token關鍵字)。
  2. 觸發經過身份驗證的事件后,強制導航到所需的路由,以便應用程序識別登錄。

您可以創建以下類:

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { Location } from '@angular/common';

@Injectable()
export class AuthenticationCallbackActivateGuard implements CanActivate {

  constructor(private location: Location) { }

  canActivate() {
    // You may want to make a more robust check here
    return this.location.path(true).indexOf("access_token") === -1;
  }
}

注冊為您的家庭路線的警衛:

const appRoutes: Routes = [
  { path: '', component: HomeComponent, canActivate: [AuthenticationCallbackActivateGuard] },
  { path: '**', redirectTo: '' }
];

export const appRoutingProviders: any[] = [
  AuthenticationCallbackActivateGuard
];

最后,在身份驗證后導航到您的路線:

this.lock.on('authenticated', (authResult) => {
  localStorage.setItem('id_token', authResult.idToken);
  this.router.navigate([''], {});
});

解決方法#2 - (angular/core@2.4.1,angular/router@3.4.1,lock@10.7)

與之前的操作類似,但是必需的導航是在防護裝置上完成的 ,並且認證回調數據作為片段提供,以便Lock能夠在處理事件時看到此信息。 由於導航移動到防護,您不再需要在鎖定身份驗證事件上進行導航。

創建以下類:

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { Location } from '@angular/common';
import { Router } from '@angular/router';

@Injectable()
export class AuthenticationCallbackActivateGuard implements CanActivate {

  constructor(private router: Router, private location: Location) { }

  canActivate() {
    var path = this.location.path(true);

    // You may want to make a more robust check here
    var isAuthenticationCallback = path.indexOf("access_token") !== -1;

    if (isAuthenticationCallback) {
      this.router.navigate([''], { fragment: path });

      return false;
    }

    return true;
  }
}

注冊為您的家庭路線的警衛:

const appRoutes: Routes = [
  { path: '', component: HomeComponent, canActivate: [AuthenticationCallbackActivateGuard] },
  { path: '**', redirectTo: '' }
];

export const appRoutingProviders: any[] = [
  AuthenticationCallbackActivateGuard
];

最后,處理身份驗證事件:

this.lock.on('authenticated', (authResult) => {
  localStorage.setItem('id_token', authResult.idToken);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM