簡體   English   中英

Auth0和Angular 2:使用登錄小部件登錄和路由失敗

[英]Auth0 and Angular 2: login and routing failing using the login widget

我開始開發Web應用程序,並選擇Angular 2作為前端框架。 我目前正在嘗試使用Auth0進行用戶授權。 問題如下:我正在嘗試實現登錄頁面登錄->重定向功能。 打開網站后,應立即檢查localStorage是否有用戶令牌,然后顯示登錄小部件或重定向到主頁。 但是我遇到了一個非常討厭的錯誤:

當我登錄時,頁面刷新,並且小部件再次出現: tokenNotExpired()由於某種原因返回false 我按相同的憑據再次登錄-頁面刷新,登錄小部件消失,日志記錄顯示tokenNotExpired()現在返回true ,但是我的重定向仍然無效。 如果現在僅輸入我的基本地址http://localhost:4200 ,它將成功將我重定向到hometokenNotExpired()返回true

我嘗試調試它,但沒有任何運氣-我找不到它出故障的地方。

本質上,由於缺乏經驗,我非常確定在編碼重定向功能時會遇到問題。 一直以來,我都非常感謝您的幫助。

我包括我的代碼節選,省略了多余的部分。 我正在通過在main.ts中引導引導服務來全局注入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)
];

登錄-page.component.ts:

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();
    }
  }
}

auth.service.ts:

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;
  }
}

auth.guard.ts:

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;
    }
  }
}

admin.guard.ts:

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將對redirectUrl進行GET調用。 此呼叫阻止您通過authenticated事件觸發。 因此,在您的auth.service.ts文件中:

lock = new Auth0Lock('omitted', 'omitted', {
  closable: false,
  auth: { // <--- mind this nesting
    redirect: false
  }
});

這將在登錄時在服務中調用“已驗證”事件。 登錄完成后,您可能還希望重定向用戶。 因此,在回調中調用this._router.navigate(['path']) 不要忘記import { Router } from 'angular/router'並在構造函數中創建實例: constructor(private _router: Router) {}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM