如何将 HashLocationStrategy 与 Auth0 Lock 小部件结合使用以进行用户登录

2024-03-14

更新后Auth0登录示例 https://github.com/auth0-samples/auth0-angular-samples/tree/master/01-Login to use HashLocationStrategy in app.module.ts:

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

Auth0 锁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 路由器在匹配路由后从路径中去除额外的参数 https://github.com/angular/angular/issues/11233 and 导航不应保留查询参数和片段 https://github.com/angular/angular/commit/23ee29b6a2ae396f6ec13f71c9552e3e0a983c3c一些背景。

执行登录后,Auth0 将请求您的浏览器导航到类似于以下内容的 URL:

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

此 URL 包含 Lock 识别用户已通过身份验证所需的所有信息,但是,前面提到的 Angular 路由器行为意味着在 Lock 之前当有机会处理此信息时,URL 片段中包含的身份验证数据将被剥离,将 URL 保留为 (http://example.com/#/)。发生这种情况是因为您很可能配置了与任何 URL 匹配的包罗万象的路由。

假设您配置了以下路由:

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

免责声明:下面显示的第一个解决方案是作为解决方法提供的,经证明对 Angular 有效2.0.0, 角路由器3.0.0与锁一起使用10.2。从那时起,路由器和/或锁似乎发生了变化,导致最初的解决方法失败了。我提供了第二种解决方法,它似乎适用于 Angular2.4.1, 角路由器3.4.1和锁定10.7.


解决方法#1 - (角度/[电子邮件受保护] /cdn-cgi/l/email-protection, 角度/[电子邮件受保护] /cdn-cgi/l/email-protection, [电子邮件受保护] /cdn-cgi/l/email-protection)

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

  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 - (角度/[电子邮件受保护] /cdn-cgi/l/email-protection, 角度/[电子邮件受保护] /cdn-cgi/l/email-protection, [电子邮件受保护] /cdn-cgi/l/email-protection)

与之前所做的类似,但是命令式导航是在守卫本身上完成的以片段形式提供身份验证回调数据,以便 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);
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 HashLocationStrategy 与 Auth0 Lock 小部件结合使用以进行用户登录 的相关文章

随机推荐

  • python ssl eof 发生违反协议、wantwriteerror、zeroreturnerror

    我正在使用 gevent 为池运行许多 celery 任务 20 000 也用猴子修补所有任务 这些任务中的每一个都会调用 adwords 等第三方服务来提取数据 由于潜在的 SSL 错误 我的任务不断失败 下面是一些异常的堆栈跟踪 排名不
  • 正则表达式从捕获中排除匹配项

    在 Net 中使用正则表达式 我将有一组类似这样的数据 lt Bunch o Data Here gt where lt 只是新记录的指标 gt 是记录的结尾 这些记录可能会像这样出现 lt Dataset 1 gt
  • C++ 矢量数学和 OpenGL 兼容

    我一直在做很多矢量数学的工作 并为其编写了自己的模板 我的要求是大量的向量数学 加法 减法 缩放 叉乘和点积 而且我需要能够将我的向量作为 float 传递 以便 openGL 可以使用它 我已经很高兴地使用这个有一段时间了 今天一位讲师看
  • Codeigniter:如何获取文件的文件名

    我是 Codeigniter 新手 我正在尝试获取上传图像的文件名 以便将其保存在数据库中 我有两个模型 homemodel 处理我的数据库 image upload model 处理图像上传 一切正常 除了我不知道如何将图像文件名发布到数
  • 如何在 Xcode 5 中的 Storyboard 上抑制约束和布局警告?

    是否有任何标志可以抑制 Xcode 5 中故事板的不明确布局或错误放置的视图 我在代码中添加约束 并且只是使用 Interfacebuilder 中的视图作为虚拟对象 我不想应用 Xcode Resolve 自动布局问题 因为我很高兴视图在
  • 当我登录 Azure 门户时,Azure Function 计时器运行两次

    我在 Azure 中有一个定时函数应用程序 计划在每天 22 00 运行 然而 它似乎每天都在 21 59 和 22 00 运行 当我登录 Azure 门户检查日志时 它似乎也是随机运行的 以下是我收到的重复条目的时间戳示例 我在网上搜索过
  • ASP.Net MVC 应该为每个视图创建一个模型吗?

    我对 ASP Net MVC 相当陌生 我发现自己为每个视图制作一个模型类 例如 SignInModel SignUpModel EditProfileModel 等 其中许多都有些相似 具有相同的数据库文件 然后还有一些自定义属性 这真的
  • PyInstaller 无缓冲 stdio

    Problem Docker 镜像大小通常应尽可能小 使用成熟的环境 例如标准蟒蛇 https hub docker com python 安装了所有依赖项后 图像通常会导致图像严重膨胀 将 python 打包成独立的可执行文件 例如使用
  • c# MVC 站点地图 - 使用角色时非常慢 - 非常慢

    我已经安装了适用于 MVC5 的 MVC 站点地图提供程序 并且使用了开箱即用的所有内容 效果很好 现在我想实现基于角色的菜单修剪 所以假设我的控制器 public class Home Controller Authorize Roles
  • 如何调试“请求的资源上不存在‘Access-Control-Allow-Origin’标头”

    我在浏览器控制台上显示此错误 XMLHttpRequest 无法加载http localhost 8080 api 登录 http localhost 8080 api login 请求的资源上不存在 Access Control Allo
  • 当 DOM“准备好”时运行 JavaScript 函数?

    我正在使用 JavaScript 上传脚本 该脚本表示一旦 DOM 准备好就运行初始化函数 我目前可以通过调用该函数来使其正常工作body onload或者直接在函数定义之后 该函数在占位符 div 中构建一些 HTML 充当文件上传工具
  • 向 NSImageView 添加阴影

    我有一个NSImageView并想添加阴影 我尝试过以编程方式执行此操作 NSShadow shadow NSShadow alloc init autorelease shadow setShadowBlurRadius 4 0f sha
  • 打印不带括号的 Numpy 数组

    predictions x6 x5 x4 x3 x2 x1 predictions 调用上面的列表会产生以下数组 array 782 36739152 array 783 31415872 array 726 90474426 array
  • 在单元测试中模拟 Spark RDD

    是否可以在不使用sparkContext的情况下模拟RDD 我想对以下实用函数进行单元测试 def myUtilityFunction data1 org apache spark rdd RDD myClass1 data2 org ap
  • 如何使用 CSS 创建对角线背景效果

    是否可以使用 CSS 创建如下图所示的效果 基本上我想创建 div 背景对角线分割 一侧为块色 另一侧为白色 您可以使用linear gradient on background 请参见以下示例 body height 100vh widt
  • C语言中localtime的结果结构体是如何分配的?

    我正在玩time hC 语言文件可以帮助我们处理时间 日期函数 我碰到 struct tm Cdecl localtime const time t timer 这似乎返回一个指向 tm 结构的指针 我发现按地址返回主要用于返回新的内存分配
  • 导入错误未定义符号(python 中的 C++ 模块)ZTINSt8ios_base7failureB5cxx11E

    我知道网站上有很多类似的问题 但我找不到问题的答案 我使用 Cython 包装 C 类 以便将它们与 Python3 一起使用 使用以下命令构建外部模块后setup py 当我运行 python 程序时 出现以下错误 from name o
  • MYSQL - 选择两个表中行数的差异

    我正在尝试比较两个数据库中两个表的行数 行数应该相同 SELECT 从 db1 table1 中选择 COUNT 从 db2 table1 中选择 COUNT AS差异 仅当差异 0 时如何选择 我需要为多个表运行此命令 并且不需要 0 值
  • R RegEx:匹配方括号内的所有双引号 (") 字符

    我正在努力获取匹配所有双引号字符的正则表达式 出现在方括号内 我有不同的部分可以完成我想要的部分功能 例如 gsub xyz 1 xyz 将得到所有双引号 无论其他什么 gsub xyz abc 1 abc 将把所有内容放在两个方括号内 包
  • 如何将 HashLocationStrategy 与 Auth0 Lock 小部件结合使用以进行用户登录

    更新后Auth0登录示例 https github com auth0 samples auth0 angular samples tree master 01 Login to use HashLocationStrategy in ap