[英]Auth0 and Angular 2: login and routing failing using the login widget
I am starting to develop web applications and chose Angular 2 as the front-end framework. 我开始开发Web应用程序,并选择Angular 2作为前端框架。 I'm currently trying out Auth0 for user authorisation.
我目前正在尝试使用Auth0进行用户授权。 The problem is as follows: I am trying to implement a landing page login -> redirect functionality.
问题如下:我正在尝试实现登录页面登录->重定向功能。 Immediately after opening the website it should check if there is a user's token in the
localStorage
and then either show the login widget or redirect to the home page. 打开网站后,应立即检查
localStorage
是否有用户令牌,然后显示登录小部件或重定向到主页。 But I have ran into this very nasty bug: 但是我遇到了一个非常讨厌的错误:
When i'm logging in, the page refreshes and the widget appears again: tokenNotExpired()
for some reason returns false
. 当我登录时,页面刷新,并且小部件再次出现:
tokenNotExpired()
由于某种原因返回false
。 I press to login again with the same credentials - page refreshes, login widget disappears, logging shows that tokenNotExpired()
is returning true
now, but my redirect still doesn't work. 我按相同的凭据再次登录-页面刷新,登录小部件消失,日志记录显示
tokenNotExpired()
现在返回true
,但是我的重定向仍然无效。 If I now just enter my base address, http://localhost:4200
, it successfully redirects me to home
and tokenNotExpired()
returns true
. 如果现在仅输入我的基本地址
http://localhost:4200
,它将成功将我重定向到home
, tokenNotExpired()
返回true
。
I tried debugging it but without any luck - I can't find where it is failing. 我尝试调试它,但没有任何运气-我找不到它出故障的地方。
Essentially, I am very sure there are problems in the way I approach coding the redirect feature, since my lack of experience. 本质上,由于缺乏经验,我非常确定在编码重定向功能时会遇到问题。 I would very kindly appreciate any help, been sitting on this for a while.
一直以来,我都非常感谢您的帮助。
I'm including excerpts of my code omitting the redundant parts. 我包括我的代码节选,省略了多余的部分。 I am injecting the Auth service globally by bootstrapping it in main.ts.
我正在通过在main.ts中引导引导服务来全局注入Auth服务。
app.routes.ts: 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)
];
login-page.component.ts: 登录-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: 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: 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: 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;
}
}
}
You must set redirect: false
in the configuration since it is a single page app. 您必须在配置中设置
redirect: false
,因为它是单页应用程序。 Auth0 will otherwise make a GET call to the redirectUrl
. 否则,Auth0将对
redirectUrl
进行GET调用。 This call is preventing your authenticated
event from firing up. 此呼叫阻止您通过
authenticated
事件触发。 Thus, in your auth.service.ts file: 因此,在您的auth.service.ts文件中:
lock = new Auth0Lock('omitted', 'omitted', {
closable: false,
auth: { // <--- mind this nesting
redirect: false
}
});
This will invoke the 'authenticated' event in the service on login. 这将在登录时在服务中调用“已验证”事件。 You probably also want to redirect the user once login is done.
登录完成后,您可能还希望重定向用户。 Thus, in the callback invoke
this._router.navigate(['path'])
. 因此,在回调中调用
this._router.navigate(['path'])
。 Don't forget to import { Router } from 'angular/router'
and creating an instance in the constructor: constructor(private _router: Router) {}
. 不要忘记
import { Router } from 'angular/router'
并在构造函数中创建实例: constructor(private _router: Router) {}
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.