[英]How to use the HashLocationStrategy with the Auth0 Lock widget for user login
更新后Auth0登錄樣品使用HashLocationStrategy
在app.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 。
嘗試繞過此默認行為的一種可能方法是執行以下步驟:
access_token
關鍵字)。 您可以創建以下類:
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([''], {});
});
與之前的操作類似,但是必需的導航是在防護裝置上完成的 ,並且認證回調數據作為片段提供,以便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.