[英]Auth0 and Angular 2: login and routing failing using the login widget
我開始開發Web應用程序,並選擇Angular 2作為前端框架。 我目前正在嘗試使用Auth0進行用戶授權。 問題如下:我正在嘗試實現登錄頁面登錄->重定向功能。 打開網站后,應立即檢查localStorage
是否有用戶令牌,然后顯示登錄小部件或重定向到主頁。 但是我遇到了一個非常討厭的錯誤:
當我登錄時,頁面刷新,並且小部件再次出現: tokenNotExpired()
由於某種原因返回false
。 我按相同的憑據再次登錄-頁面刷新,登錄小部件消失,日志記錄顯示tokenNotExpired()
現在返回true
,但是我的重定向仍然無效。 如果現在僅輸入我的基本地址http://localhost:4200
,它將成功將我重定向到home
, tokenNotExpired()
返回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.