如何使用Angular 2 useHash设置Auth0:是吗? [英] How do I set up Auth0 with Angular 2 useHash: true?

查看:55
本文介绍了如何使用Angular 2 useHash设置Auth0:是吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关使用散列路由在角2中使用auth0的文档和示例(例如 http://somdomain. com/#/someroute )非常稀疏且过时.

The documentation and samples around using auth0 with angular 2 using hash routing (e.g. http://somdomain.com/#/someroute ) is pretty sparse and out of date.

有多个问题要解决:

  1. auth0库侦听URL片段的更改.不幸的是,angular吞噬了URL片段更改,因为它认为它正在处理路由.

  1. auth0 librarylistens for a change in URL fragment. Unfortunately, angular swallows the URL fragment change because it thinks it is dealing with a route.

URL片段以#access_token=...开头,并且由于未将access_token注册为路由,角度引发了错误.

the url fragment begins with #access_token=... and angular throws an error because access_token is not registered as a route.

即使您注册了一条路线access_token,您也不想以任何方式将其显示为一条路线,因此您需要取消导航.

even if you register a route access_token you don't want to display it as a route any way, so you need to cancel the navigation.

要真正设置它,必须做些什么?

What are all the things one has to do to actually set it up?

推荐答案

首先,您需要auth0-lock

 npm install --save auth0-lock

接下来,您将需要身份验证服务.以下身份验证服务实现login()logout().

Next, you'll need an authentication service. The following Authentication Service implements login() and logout().

在调用这些方法之前,请确保使用registerAuthenticationWithHashHandler配置服务.这可以在App.Component.ts

Before calling these methods, make sure you configure the service with registerAuthenticationWithHashHandler. This can be done in App.Component.ts

// AuthService.ts
import { environment } from './../environments/environment';
import { Injectable } from '@angular/core';
import { Router, RouterEvent } from '@angular/router';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/take';
import { AuthCallbackComponent } from './../app/auth-callback/auth-callback.component';
import { AuthenticationCallbackActivateGuard } from '../app/auth-callback/auth-callback-activate-guard';
import Auth0Lock from 'auth0-lock';

@Injectable()
export class AuthService {

  private lock: Auth0Lock;

  constructor(public router: Router) {

    this.lock = new Auth0Lock(
      environment.auth0.clientID,
      environment.auth0.domain,
      {
        oidcConformant: true,
        autoclose: true,
        auth: {
          autoParseHash: false,
          redirectUrl: environment.auth0.redirectUri,
          responseType: 'token id_token',
          audience: environment.auth0.audience,
          params: {
            scope: 'openid'
          }
        }
      }
    );

  }

  public login(): void {
    this.lock.show();
  }

  // Call this method in app.component.ts
  // if using path-based routing
  public registerAuthenticationHandler(): void {
    this.lock.on('authenticated', (authResult) => {
      if (authResult && authResult.accessToken && authResult.idToken) {
        this.setSession(authResult);
        this.router.navigate(['/']);
      }
    });
    this.lock.on('authorization_error', (err) => {
      this.router.navigate(['/']);
      console.log(err);
      alert(`Error: ${err.error}. Check the console for further details.`);
    });
  }

  // Call this method in app.component.ts
  // if using hash-based routing
  public registerAuthenticationWithHashHandler(): void {

    this.registerAuthenticationHandler();
    this.workaroundHashAccessTokenRoute();

    this.router.events.take(1).subscribe(event => {

      if (!(event instanceof RouterEvent)) {
        return;
      }

      this.lock.resumeAuth(window.location.hash, (err, authResult) => {
        if (authResult && authResult.idToken) {
          this.lock.emit('authenticated', authResult);
        }

        if (authResult && authResult.error) {
          this.lock.emit('authorization_error', authResult);
        }
      });

    });
  }

  private workaroundHashAccessTokenRoute() {

    /* workaround useHash:true with angular2 router
    ** Angular mistakenly thinks "#access_token" is a route
    ** and we oblige by creating a fake route that can never be activated
    */
    const routes = this.router.config;
    routes.splice(0, 0, {
      path: 'access_token',
      component: AuthCallbackComponent,
      canActivate: [AuthenticationCallbackActivateGuard]
    });
    this.router.resetConfig(routes);
  }

  private setSession(authResult): void {
    // Set the time that the access token will expire at
    const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
    localStorage.setItem('access_token', authResult.accessToken);
    localStorage.setItem('id_token', authResult.idToken);
    localStorage.setItem('expires_at', expiresAt);
  }

  public logout(): void {
    // Remove tokens and expiry time from localStorage
    localStorage.removeItem('access_token');
    localStorage.removeItem('id_token');
    localStorage.removeItem('expires_at');
    // Go back to the home route
    this.router.navigate(['/']);
  }

  public isAuthenticated(): boolean {
    // Check whether the current time is past the
    // access token's expiry time
    const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
    return new Date().getTime() < expiresAt;
  }
}

registerAuthenticationWithHashHandler创建一个名为"access_token"的虚拟路由,并受到名为AuthenticationCallbackActivateGuard的规则的保护,该规则始终返回false.

The registerAuthenticationWithHashHandler creates a dummy route called "access_token" and it is protected by a rule called AuthenticationCallbackActivateGuard that always returns false.

// auth-callback-activate-guard.ts
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() {
    return false;
  }
}

以下是虚拟路线所需的部分:

Here are the parts you'll need for the dummy routes:

// auth-callback/auth-callback.components.ts
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-auth-callback',
  templateUrl: './auth-callback.component.html',
  styleUrls: ['./auth-callback.component.scss']
})
export class AuthCallbackComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

在App.Component.ts中注册身份验证服务

Registering Authentication Service in App.Component.ts

// app/app.component.ts
import { Component } from '@angular/core';
import { AuthService } from '../services/auth.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  constructor(private auth: AuthService) {
    auth.registerAuthenticationWithHashHandler();
  }
}

这篇关于如何使用Angular 2 useHash设置Auth0:是吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆