加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angular – 如何将HashLocationStrategy与Auth0 Lock小部件一起

发布时间:2020-12-17 17:04:43 所属栏目:安全 来源:网络整理
导读:更新 Auth0 login sample后,在app.module.ts中使用HashLocationStrategy: import { LocationStrategy,HashLocationStrategy } from '@angular/common';// (...)@NgModule({ providers: [ {provide: LocationStrategy,useClass: HashLocationStrategy},appRo
更新 Auth0 login sample后,在app.module.ts中使用HashLocationStrategy:

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

Auth0 Lock经过身份验证的事件不再被引发:

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 Router strips extra arguments from the path after matching a route和 navigation should not preserve query params and fragment.

执行登录后,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: '' }
];

DISCLAIMER: The first solution that will be shown below was provided as a workaround that proved functional for Angular 2.0.0,Angular router 3.0.0 used with Lock 10.2. Since then,it seems the router and/or Lock suffered changes that made the initial workaround fail. I’m providing a second workaround that seems to be functional with Angular 2.4.1,Angular router 3.4.1 and Lock 10.7.

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

尝试绕过此默认行为的一种可能方法是执行以下步骤:

>向处理身份验证回调请求的路由添加激活防护,以便在当前URL看起来像是登录结果时不允许路由激活(例如,在其片段中包含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] },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: '',处理身份验证事件:

this.lock.on('authenticated',authResult.idToken);
});

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读