我开始开发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;
}
}
}
答案 0 :(得分:5)
您必须在配置中设置redirect: false
,因为它是单页应用。否则,Auth0将对redirectUrl
进行GET调用。此调用阻止您的authenticated
事件触发。因此,在 auth.service.ts 文件中:
lock = new Auth0Lock('omitted', 'omitted', {
closable: false,
auth: { // <--- mind this nesting
redirect: false
}
});
这将在登录时调用服务中的“authenticated”事件。登录完成后,您可能还希望重定向用户。因此,在回调调用this._router.navigate(['path'])
中。不要忘记import { Router } from 'angular/router'
并在构造函数中创建实例:constructor(private _router: Router) {}
。