Auth0要求您在身份验证后将回调网址列入白名单,这样您就无法使用/ thing / 1,/ thing / 1001这样的网址登录应用程序中的任何页面,因为这样就无法通配符东西ID。
这个Github conversation指向我在Angular 2中解释为:
的整洁解决方案在我的auth.service.ts中:
lock = new Auth0Lock('Client_ID', 'Domain', {
auth: {
redirectUrl: window.location.origin + '/login',
responseType: 'token',
params: {
scope: 'openid name email',
state: JSON.stringify({pathname: window.location.pathname})
}
}
});
然后我可以在Angular 2中将我的/登录路由列入白名单。我尝试让我的login.component.ts读取然后导航到Auth0在回调中返回的路径名,如下所示:
this.route
.queryParams
.subscribe(params => {
this.state = params['state'];
this.router.navigate(this.state, {preserveQueryParams: true});
});
...但是params似乎总是空的。据我所知,这是因为回调网址的格式如下:
... Angular 2路由会在到达LoginComponent之前自动剥离#参数。
然后我发现lock.authenticated上的authResult仍然在auth.service.ts中包含我的状态参数,所以试图导航到它,如下所示:
this.lock.on("authenticated", (authResult:any) => {
localStorage.setItem('id_token', authResult.idToken);
let state: string = JSON.parse(authResult.state);
this.router.navigate([state.pathname], {});
这似乎最初起作用,但事实证明,并非可靠......它似乎在不可预测的地方重定向我
/thing/1001 to
/things or even
/
......我无法解决原因。非常感谢任何帮助。
编辑回应@ shusson的回答:
基于@ shusson的答案的工作代码在auth.service.ts中:
export class Auth {
// Configure Auth0
lock = new Auth0Lock('Client_ID', 'Domain',{
auth: {
redirectUrl: location.origin + '/login',
responseType: 'token',
}
});
constructor(private router: Router, route: ActivatedRoute) {
// Add callback for lock `authenticated` event
this.lock.on("authenticated", (authResult:any) => {
localStorage.setItem('id_token', authResult.idToken);
let state: any = JSON.parse(authResult.state);
this.router.navigate([state.pathname], {});
...
}
public login() {
// Call the show method to display the widget.
this.lock.show({
auth: {
params: {
scope: 'openid name email',
state: JSON.stringify({pathname: this.router.url})
}
}
});
};
编辑:基于this comment re:在回调中传递路径是CSRF漏洞:
我的auth.service.ts中的最终工作代码是:
import { Injectable } from '@angular/core';
import { tokenNotExpired } from 'angular2-jwt/angular2-jwt';
import { Router, ActivatedRoute } from '@angular/router';
import { UUID } from 'angular2-uuid/index';
// Avoid name not found warnings
declare var Auth0Lock: any;
@Injectable()
export class Auth {
// Configure Auth0
lock = new Auth0Lock('Client_ID', 'Domain',{
auth: {
redirectUrl: location.origin + '/login',
responseType: 'token',
}
});
//Store profile object in auth class
userProfile: Object;
constructor(private router: Router, route: ActivatedRoute) {
// Set userProfile attribute of already saved profile
this.userProfile = JSON.parse(localStorage.getItem('profile'));
// Add callback for lock `authenticated` event
this.lock.on("authenticated", (authResult:any) => {
localStorage.setItem('id_token', authResult.idToken);
let pathname_object: any = JSON.parse(authResult.state);
let pathname: any = localStorage.getItem(pathname_object.pathname_key);
//get rid of localStorage of url
localStorage.removeItem(pathname_object.pathname_key);
//navigate to original url
this.router.navigate([pathname], {});
// Fetch profile information
this.lock.getProfile(authResult.idToken, (error:any, profile:any) => {
if (error) {
// Handle error
alert(error);
return;
}
localStorage.setItem('profile', JSON.stringify(profile));
this.userProfile = profile;
});
});
}
public login() {
//generate UUID against which to store path
let uuid = UUID.UUID();
localStorage.setItem(uuid, this.router.url);
// Call the show method to display the widget.
this.lock.show({
auth: {
params: {
scope: 'openid name email',
state: JSON.stringify({pathname_key: uuid})
}
}
});
};
...
}
答案 0 :(得分:1)
在我们的身份验证服务中,我们会做类似的事情:
const options: any = {
auth: {
redirectUrl: location.origin,
responseType: 'token'
},
};
constructor(private router: Router) {
new Auth0Lock(environment.auth0ClientId, environment.auth0Domain, options);
...
this.lock.on('authenticated', (authResult: any) => {
...
this.router.navigateByUrl(authResult.state);
});
}
public login() {
this.lock.show({
auth: {
params: {state: this.router.url},
}
});
};