Angular 4 隐式流回调和路由保护
Angular 4 Implicit Flow Callback and Router Guard
在Angular 4 中处理隐式流回调的最佳方法是什么?我希望 Guard 等到用户使用令牌重定向回并且它存储在 Guard returns true 或 false 之前,在我被重定向回检查令牌。有没有比我正在做的更好的方法来处理 AuthGuard,这样我就不会在身份验证完成之前得到拒绝访问?
如何让路由器守卫等待重定向?
AppComponent
ngOnInit() {
//if there is a hash then the user is being redirected from the AuthServer with url params
if (window.location.hash && !this.authService.isUserLoggedIn()) {
//check the url hash
this.authService.authorizeCallback();
}
else if (!this.authService.isUserLoggedIn()) {
//try to authorize user if they aren't login
this.authService.tryAuthorize();
}
}
AuthSerivce
tryAuthorize() {
//redirect to open id connect /authorize endpoint
window.location.href = this.authConfigService.getSignInEndpoint();
}
authorizeCallback() {
let hash = window.location.hash.substr(1);
let result: any = hash.split('&').reduce(function (result: any, item: string) {
let parts = item.split('=');
result[parts[0]] = parts[1];
return result;
}, {});
if (result.error && result.error == 'access_denied') {
this.navigationService.AccessDenied();
}
else {
this.validateToken(result);
}
}
isUserLoggedIn(): boolean {
let token = this.getAccessToken();
//check if there is a token
if(token === undefined || token === null || token.trim() === '' )
{
//no token or token is expired;
return false;
}
return true;
}
getAccessToken(): string {
let token = <string>this.storageService.get(this.accessTokenKey);
if(token === undefined || token === null || token.trim() === '' )
{
return '';
}
return token;
}
resetAuthToken() {
this.storageService.store(this.accessTokenKey, '');
}
validateToken(tokenResults: any) {
//TODO: add other validations
//reset the token
this.resetAuthToken();
if (tokenResults && tokenResults.access_token) {
//store the token
this.storageService.store(this.accessTokenKey, tokenResults.access_token);
//navigate to clear the query string parameters
this.navigationService.Home();
}
else {
//navigate to Access Denied
this.navigationService.AccessDenied();
}
}
}
AuthGuard
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot){
var hasAccess = this.authService.isUserLoggedIn();
if(!hasAccess)
{
this.naviationService.AccessDenied();
return false;
}
return true;
}
CanActivate
方法可以 return 一个 Observable
、Promise
或 Boolean
,并且 Angular 将知道解包它并处理所有异步。您可以更改代码以在 returning completed/failed Observable
或 resolved/rejected Promise
到 Angular 路由器之前检查必要的数据,并作为该异步函数的结果调用 this.naviationService.AccessDenied()
。
如果你想让你的警卫等待异步任务,你需要将你的 AuthService 更改为 return 一个可观察的并发出你想要等待的异步任务中你需要的值,在你的情况下它减少()。之后在守卫中订阅。这样你就可以让你的守卫等待任何异步任务。
AuthGuard
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot){
this.authService.isUserLoggedIn().map(logged => {
if (logged) {
return true;
} else {
this.naviationService.AccessDenied();
return false;
}
}).catch(() => {
this.naviationService.AccessDenied();
return Observable.of(false);
});
}
}
AuthService 的一部分
isUserLoggedIn(): Observable<boolean> {
return new Observable((observer) => {
let hash = window.location.hash.substr(1);
let result: any = hash.split('&').reduce(function (result: any, item: string) {
let parts = item.split('=');
result[parts[0]] = parts[1];
if (result.error && result.error == 'access_denied') {
observer.next(false);
observer.complete();
}
else {
this.validateToken(result);
}
let token = this.getAccessToken();
//check if there is a token
if(token === undefined || token === null || token.trim() === '' )
{
//no token or token is expired;
observer.next(false);
observer.complete();
}
observer.next(true);
observer.complete();
}, {});
});
}
在Angular 4 中处理隐式流回调的最佳方法是什么?我希望 Guard 等到用户使用令牌重定向回并且它存储在 Guard returns true 或 false 之前,在我被重定向回检查令牌。有没有比我正在做的更好的方法来处理 AuthGuard,这样我就不会在身份验证完成之前得到拒绝访问?
如何让路由器守卫等待重定向?
AppComponent
ngOnInit() {
//if there is a hash then the user is being redirected from the AuthServer with url params
if (window.location.hash && !this.authService.isUserLoggedIn()) {
//check the url hash
this.authService.authorizeCallback();
}
else if (!this.authService.isUserLoggedIn()) {
//try to authorize user if they aren't login
this.authService.tryAuthorize();
}
}
AuthSerivce
tryAuthorize() {
//redirect to open id connect /authorize endpoint
window.location.href = this.authConfigService.getSignInEndpoint();
}
authorizeCallback() {
let hash = window.location.hash.substr(1);
let result: any = hash.split('&').reduce(function (result: any, item: string) {
let parts = item.split('=');
result[parts[0]] = parts[1];
return result;
}, {});
if (result.error && result.error == 'access_denied') {
this.navigationService.AccessDenied();
}
else {
this.validateToken(result);
}
}
isUserLoggedIn(): boolean {
let token = this.getAccessToken();
//check if there is a token
if(token === undefined || token === null || token.trim() === '' )
{
//no token or token is expired;
return false;
}
return true;
}
getAccessToken(): string {
let token = <string>this.storageService.get(this.accessTokenKey);
if(token === undefined || token === null || token.trim() === '' )
{
return '';
}
return token;
}
resetAuthToken() {
this.storageService.store(this.accessTokenKey, '');
}
validateToken(tokenResults: any) {
//TODO: add other validations
//reset the token
this.resetAuthToken();
if (tokenResults && tokenResults.access_token) {
//store the token
this.storageService.store(this.accessTokenKey, tokenResults.access_token);
//navigate to clear the query string parameters
this.navigationService.Home();
}
else {
//navigate to Access Denied
this.navigationService.AccessDenied();
}
}
}
AuthGuard
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot){
var hasAccess = this.authService.isUserLoggedIn();
if(!hasAccess)
{
this.naviationService.AccessDenied();
return false;
}
return true;
}
CanActivate
方法可以 return 一个 Observable
、Promise
或 Boolean
,并且 Angular 将知道解包它并处理所有异步。您可以更改代码以在 returning completed/failed Observable
或 resolved/rejected Promise
到 Angular 路由器之前检查必要的数据,并作为该异步函数的结果调用 this.naviationService.AccessDenied()
。
如果你想让你的警卫等待异步任务,你需要将你的 AuthService 更改为 return 一个可观察的并发出你想要等待的异步任务中你需要的值,在你的情况下它减少()。之后在守卫中订阅。这样你就可以让你的守卫等待任何异步任务。
AuthGuard
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot){
this.authService.isUserLoggedIn().map(logged => {
if (logged) {
return true;
} else {
this.naviationService.AccessDenied();
return false;
}
}).catch(() => {
this.naviationService.AccessDenied();
return Observable.of(false);
});
}
}
AuthService 的一部分
isUserLoggedIn(): Observable<boolean> {
return new Observable((observer) => {
let hash = window.location.hash.substr(1);
let result: any = hash.split('&').reduce(function (result: any, item: string) {
let parts = item.split('=');
result[parts[0]] = parts[1];
if (result.error && result.error == 'access_denied') {
observer.next(false);
observer.complete();
}
else {
this.validateToken(result);
}
let token = this.getAccessToken();
//check if there is a token
if(token === undefined || token === null || token.trim() === '' )
{
//no token or token is expired;
observer.next(false);
observer.complete();
}
observer.next(true);
observer.complete();
}, {});
});
}