Auth0和Angular 2:使用登录小部件登录和路由失败

Auth0和Angular 2:使用登录小部件登录和路由失败,angular,jwt,angular2-routing,auth0,Angular,Jwt,Angular2 Routing,Auth0,我开始开发web应用程序,并选择Angular 2作为前端框架。我目前正在试用Auth0进行用户授权。 问题如下: 我正在尝试实现登录页面->重定向功能。打开网站后,应立即检查localStorage中是否有用户令牌,然后显示登录小部件或重定向到主页。但我遇到了一个非常讨厌的错误: 当我登录时,页面刷新,小部件再次出现:tokenNotExpired()出于某种原因返回false。我按下以使用相同的凭据再次登录-页面刷新,登录小部件消失,日志显示tokenNotExpired()现在返回true

我开始开发web应用程序,并选择Angular 2作为前端框架。我目前正在试用Auth0进行用户授权。 问题如下: 我正在尝试实现登录页面->重定向功能。打开网站后,应立即检查
localStorage
中是否有用户令牌,然后显示登录小部件或重定向到主页。但我遇到了一个非常讨厌的错误:

当我登录时,页面刷新,小部件再次出现:
tokenNotExpired()
出于某种原因返回
false
。我按下以使用相同的凭据再次登录-页面刷新,登录小部件消失,日志显示
tokenNotExpired()
现在返回
true
,但我的重定向仍然不起作用。如果我现在只输入我的基本地址,
http://localhost:4200
,它成功地将我重定向到
home
tokenNotExpired()
返回
true

我试着调试它,但没有任何运气-我找不到它失败的地方

从本质上讲,我非常确定在编写重定向特性的方法上存在问题,因为我缺乏经验。我将非常感激任何帮助,我已经坐在这个有一段时间了

我包括了代码的摘录,省略了多余的部分。我通过在main.ts中引导Auth服务,在全球范围内注入Auth服务

app.routes.ts:

import {provideRouter, RouterConfig} from "@angular/router";
import {AuthGuard} from './secure/auth.guard';
import {AdminGuard} from "./secure/admin.guard";

import {UserHomeComponent} from "./main/user-cpl/user-home.component";
import {AdminHomeComponent} from "./main/admin-cpl/admin-home.component";
import {LoginPageComponent} from "./login/login-page.component";

const APP_ROUTES: RouterConfig = [

  { path: 'home', canActivate: [AuthGuard],
    children: [
      { path: '', component: UserHomeComponent },
      { path: 'admin', component: AdminHomeComponent, canActivate: [AdminGuard] },
      ] },
  { path: 'login', component: LoginPageComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '**', redirectTo: 'home', pathMatch: 'full' }
];

export const APP_ROUTES_PROVIDER = [
  provideRouter(APP_ROUTES)
];
import {Component, OnInit} from '@angular/core';
import {ROUTER_DIRECTIVES, Router} from '@angular/router';
import {Auth} from '../secure/auth.service';

@Component({
  moduleId: module.id,
  selector: 'login-page-component',
  template: `
    <router-outlet></router-outlet>  
  `,
  directives: [ROUTER_DIRECTIVES]
})
export class LoginPageComponent implements OnInit {

  constructor(private auth: Auth, private router: Router) {
  }

  ngOnInit():any {
    console.log('LOGGED IN - ' + this.auth.loggedIn());
    if (this.auth.loggedIn()) {
      if (this.auth.isAdmin()) {
        this.router.navigate(['/home/admin']);
      } else if (!this.auth.isAdmin()) {
        this.router.navigate(['/home']);
      }

    } else {
      this.auth.login();
    }
  }
}
import {Injectable} from '@angular/core';
import {tokenNotExpired} from 'angular2-jwt';

declare var Auth0Lock: any;

@Injectable()
export class Auth {
  // Configure Auth0
  lock = new Auth0Lock('omitted', 'omitted', {
    closable: false
  });

  //Store profile object in auth class
  userProfile: any;

  constructor() {
    // Set userProfile attribute if already saved profile
    this.userProfile = JSON.parse(localStorage.getItem('profile'));

    // Add callback for lock `authenticated` event
    this.lock.on("authenticated", (authResult) => {
      localStorage.setItem('id_token', authResult.idToken);

      // Fetch profile information
      this.lock.getProfile(authResult.idToken, (error, profile) => {
        if (error) {
          // Handle error
          alert(error);
          return;
        }

        localStorage.setItem('profile', JSON.stringify(profile));
        this.userProfile = profile;
      });
    });
  }

  login() {
    this.lock.show({
      callbackUrl: 'http://localhost:4200/home'
    });
  }

  logout() {
    localStorage.removeItem('profile');
    localStorage.removeItem('id_token');
    this.userProfile = undefined;
  }

  loggedIn() {
    return tokenNotExpired();
  }

  isAdmin() {
    return this.userProfile && this.userProfile.app_metadata
      && this.userProfile.app_metadata.roles
      && this.userProfile.app_metadata.roles.indexOf('admin') > -1;
  }
}
import {Injectable} from '@angular/core';
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {CanActivate} from '@angular/router';
import {Auth} from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.auth.loggedIn()) {
      console.log('AUTH GUARD PASSED');
      return true;
    } else {
      console.log('BLOCKED BY AUTH GUARD');
      this.router.navigate(['/login']);
      return false;
    }
  }
}
import {Injectable} from '@angular/core';
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {CanActivate} from '@angular/router';
import {Auth} from './auth.service';

@Injectable()
export class AdminGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.auth.isAdmin()) {
      return true;
    } else {
      return false;
    }
  }
}
登录页面.component.ts:

import {provideRouter, RouterConfig} from "@angular/router";
import {AuthGuard} from './secure/auth.guard';
import {AdminGuard} from "./secure/admin.guard";

import {UserHomeComponent} from "./main/user-cpl/user-home.component";
import {AdminHomeComponent} from "./main/admin-cpl/admin-home.component";
import {LoginPageComponent} from "./login/login-page.component";

const APP_ROUTES: RouterConfig = [

  { path: 'home', canActivate: [AuthGuard],
    children: [
      { path: '', component: UserHomeComponent },
      { path: 'admin', component: AdminHomeComponent, canActivate: [AdminGuard] },
      ] },
  { path: 'login', component: LoginPageComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '**', redirectTo: 'home', pathMatch: 'full' }
];

export const APP_ROUTES_PROVIDER = [
  provideRouter(APP_ROUTES)
];
import {Component, OnInit} from '@angular/core';
import {ROUTER_DIRECTIVES, Router} from '@angular/router';
import {Auth} from '../secure/auth.service';

@Component({
  moduleId: module.id,
  selector: 'login-page-component',
  template: `
    <router-outlet></router-outlet>  
  `,
  directives: [ROUTER_DIRECTIVES]
})
export class LoginPageComponent implements OnInit {

  constructor(private auth: Auth, private router: Router) {
  }

  ngOnInit():any {
    console.log('LOGGED IN - ' + this.auth.loggedIn());
    if (this.auth.loggedIn()) {
      if (this.auth.isAdmin()) {
        this.router.navigate(['/home/admin']);
      } else if (!this.auth.isAdmin()) {
        this.router.navigate(['/home']);
      }

    } else {
      this.auth.login();
    }
  }
}
import {Injectable} from '@angular/core';
import {tokenNotExpired} from 'angular2-jwt';

declare var Auth0Lock: any;

@Injectable()
export class Auth {
  // Configure Auth0
  lock = new Auth0Lock('omitted', 'omitted', {
    closable: false
  });

  //Store profile object in auth class
  userProfile: any;

  constructor() {
    // Set userProfile attribute if already saved profile
    this.userProfile = JSON.parse(localStorage.getItem('profile'));

    // Add callback for lock `authenticated` event
    this.lock.on("authenticated", (authResult) => {
      localStorage.setItem('id_token', authResult.idToken);

      // Fetch profile information
      this.lock.getProfile(authResult.idToken, (error, profile) => {
        if (error) {
          // Handle error
          alert(error);
          return;
        }

        localStorage.setItem('profile', JSON.stringify(profile));
        this.userProfile = profile;
      });
    });
  }

  login() {
    this.lock.show({
      callbackUrl: 'http://localhost:4200/home'
    });
  }

  logout() {
    localStorage.removeItem('profile');
    localStorage.removeItem('id_token');
    this.userProfile = undefined;
  }

  loggedIn() {
    return tokenNotExpired();
  }

  isAdmin() {
    return this.userProfile && this.userProfile.app_metadata
      && this.userProfile.app_metadata.roles
      && this.userProfile.app_metadata.roles.indexOf('admin') > -1;
  }
}
import {Injectable} from '@angular/core';
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {CanActivate} from '@angular/router';
import {Auth} from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.auth.loggedIn()) {
      console.log('AUTH GUARD PASSED');
      return true;
    } else {
      console.log('BLOCKED BY AUTH GUARD');
      this.router.navigate(['/login']);
      return false;
    }
  }
}
import {Injectable} from '@angular/core';
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {CanActivate} from '@angular/router';
import {Auth} from './auth.service';

@Injectable()
export class AdminGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.auth.isAdmin()) {
      return true;
    } else {
      return false;
    }
  }
}
auth.guard.ts:

import {provideRouter, RouterConfig} from "@angular/router";
import {AuthGuard} from './secure/auth.guard';
import {AdminGuard} from "./secure/admin.guard";

import {UserHomeComponent} from "./main/user-cpl/user-home.component";
import {AdminHomeComponent} from "./main/admin-cpl/admin-home.component";
import {LoginPageComponent} from "./login/login-page.component";

const APP_ROUTES: RouterConfig = [

  { path: 'home', canActivate: [AuthGuard],
    children: [
      { path: '', component: UserHomeComponent },
      { path: 'admin', component: AdminHomeComponent, canActivate: [AdminGuard] },
      ] },
  { path: 'login', component: LoginPageComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '**', redirectTo: 'home', pathMatch: 'full' }
];

export const APP_ROUTES_PROVIDER = [
  provideRouter(APP_ROUTES)
];
import {Component, OnInit} from '@angular/core';
import {ROUTER_DIRECTIVES, Router} from '@angular/router';
import {Auth} from '../secure/auth.service';

@Component({
  moduleId: module.id,
  selector: 'login-page-component',
  template: `
    <router-outlet></router-outlet>  
  `,
  directives: [ROUTER_DIRECTIVES]
})
export class LoginPageComponent implements OnInit {

  constructor(private auth: Auth, private router: Router) {
  }

  ngOnInit():any {
    console.log('LOGGED IN - ' + this.auth.loggedIn());
    if (this.auth.loggedIn()) {
      if (this.auth.isAdmin()) {
        this.router.navigate(['/home/admin']);
      } else if (!this.auth.isAdmin()) {
        this.router.navigate(['/home']);
      }

    } else {
      this.auth.login();
    }
  }
}
import {Injectable} from '@angular/core';
import {tokenNotExpired} from 'angular2-jwt';

declare var Auth0Lock: any;

@Injectable()
export class Auth {
  // Configure Auth0
  lock = new Auth0Lock('omitted', 'omitted', {
    closable: false
  });

  //Store profile object in auth class
  userProfile: any;

  constructor() {
    // Set userProfile attribute if already saved profile
    this.userProfile = JSON.parse(localStorage.getItem('profile'));

    // Add callback for lock `authenticated` event
    this.lock.on("authenticated", (authResult) => {
      localStorage.setItem('id_token', authResult.idToken);

      // Fetch profile information
      this.lock.getProfile(authResult.idToken, (error, profile) => {
        if (error) {
          // Handle error
          alert(error);
          return;
        }

        localStorage.setItem('profile', JSON.stringify(profile));
        this.userProfile = profile;
      });
    });
  }

  login() {
    this.lock.show({
      callbackUrl: 'http://localhost:4200/home'
    });
  }

  logout() {
    localStorage.removeItem('profile');
    localStorage.removeItem('id_token');
    this.userProfile = undefined;
  }

  loggedIn() {
    return tokenNotExpired();
  }

  isAdmin() {
    return this.userProfile && this.userProfile.app_metadata
      && this.userProfile.app_metadata.roles
      && this.userProfile.app_metadata.roles.indexOf('admin') > -1;
  }
}
import {Injectable} from '@angular/core';
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {CanActivate} from '@angular/router';
import {Auth} from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.auth.loggedIn()) {
      console.log('AUTH GUARD PASSED');
      return true;
    } else {
      console.log('BLOCKED BY AUTH GUARD');
      this.router.navigate(['/login']);
      return false;
    }
  }
}
import {Injectable} from '@angular/core';
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {CanActivate} from '@angular/router';
import {Auth} from './auth.service';

@Injectable()
export class AdminGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.auth.isAdmin()) {
      return true;
    } else {
      return false;
    }
  }
}
admin.guard.ts:

import {provideRouter, RouterConfig} from "@angular/router";
import {AuthGuard} from './secure/auth.guard';
import {AdminGuard} from "./secure/admin.guard";

import {UserHomeComponent} from "./main/user-cpl/user-home.component";
import {AdminHomeComponent} from "./main/admin-cpl/admin-home.component";
import {LoginPageComponent} from "./login/login-page.component";

const APP_ROUTES: RouterConfig = [

  { path: 'home', canActivate: [AuthGuard],
    children: [
      { path: '', component: UserHomeComponent },
      { path: 'admin', component: AdminHomeComponent, canActivate: [AdminGuard] },
      ] },
  { path: 'login', component: LoginPageComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '**', redirectTo: 'home', pathMatch: 'full' }
];

export const APP_ROUTES_PROVIDER = [
  provideRouter(APP_ROUTES)
];
import {Component, OnInit} from '@angular/core';
import {ROUTER_DIRECTIVES, Router} from '@angular/router';
import {Auth} from '../secure/auth.service';

@Component({
  moduleId: module.id,
  selector: 'login-page-component',
  template: `
    <router-outlet></router-outlet>  
  `,
  directives: [ROUTER_DIRECTIVES]
})
export class LoginPageComponent implements OnInit {

  constructor(private auth: Auth, private router: Router) {
  }

  ngOnInit():any {
    console.log('LOGGED IN - ' + this.auth.loggedIn());
    if (this.auth.loggedIn()) {
      if (this.auth.isAdmin()) {
        this.router.navigate(['/home/admin']);
      } else if (!this.auth.isAdmin()) {
        this.router.navigate(['/home']);
      }

    } else {
      this.auth.login();
    }
  }
}
import {Injectable} from '@angular/core';
import {tokenNotExpired} from 'angular2-jwt';

declare var Auth0Lock: any;

@Injectable()
export class Auth {
  // Configure Auth0
  lock = new Auth0Lock('omitted', 'omitted', {
    closable: false
  });

  //Store profile object in auth class
  userProfile: any;

  constructor() {
    // Set userProfile attribute if already saved profile
    this.userProfile = JSON.parse(localStorage.getItem('profile'));

    // Add callback for lock `authenticated` event
    this.lock.on("authenticated", (authResult) => {
      localStorage.setItem('id_token', authResult.idToken);

      // Fetch profile information
      this.lock.getProfile(authResult.idToken, (error, profile) => {
        if (error) {
          // Handle error
          alert(error);
          return;
        }

        localStorage.setItem('profile', JSON.stringify(profile));
        this.userProfile = profile;
      });
    });
  }

  login() {
    this.lock.show({
      callbackUrl: 'http://localhost:4200/home'
    });
  }

  logout() {
    localStorage.removeItem('profile');
    localStorage.removeItem('id_token');
    this.userProfile = undefined;
  }

  loggedIn() {
    return tokenNotExpired();
  }

  isAdmin() {
    return this.userProfile && this.userProfile.app_metadata
      && this.userProfile.app_metadata.roles
      && this.userProfile.app_metadata.roles.indexOf('admin') > -1;
  }
}
import {Injectable} from '@angular/core';
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {CanActivate} from '@angular/router';
import {Auth} from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.auth.loggedIn()) {
      console.log('AUTH GUARD PASSED');
      return true;
    } else {
      console.log('BLOCKED BY AUTH GUARD');
      this.router.navigate(['/login']);
      return false;
    }
  }
}
import {Injectable} from '@angular/core';
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {CanActivate} from '@angular/router';
import {Auth} from './auth.service';

@Injectable()
export class AdminGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.auth.isAdmin()) {
      return true;
    } else {
      return false;
    }
  }
}

您必须在配置中设置
redirect:false
,因为它是一个单页应用程序。否则,Auth0将对
重定向URL
进行GET调用。此调用正在阻止您的
authenticated
事件启动。因此,在您的auth.service.ts文件中:

lock = new Auth0Lock('omitted', 'omitted', {
  closable: false,
  auth: { // <--- mind this nesting
    redirect: false
  }
});
lock=newauth0lock('省略','省略'{
可关闭:错误,

auth:{//In
auth.login()
您的属性应该是
callbackURL
。我认为这对OAuth是区分大小写的。@ghg565是的,我更改了它,但它没有任何影响。我还意识到它没有使用callbackURL重定向到任何地方,而是返回到登录页面,并且第一次不存储凭据。设置redirect to false将启用“弹出模式”,该模式在文档中有以下警告:存在一个已知的错误,在某些情况下,它会阻止Android或Firefox在iOS上以及Internet Explorer中的弹出模式正常工作。因此,我们建议仅使用重定向模式或检测这些特殊情况,并有选择地启用红色直接模式。