首页 文章

登录后Angular2重定向

提问于
浏览
11

我正在使用angular2创建一个身份验证系统,其中的想法是,如果未经过身份验证的用户尝试导航到“受保护”的URL,系统会将用户重定向到登录页面,在该URL中放入一个名为“next”的查询参数“这将有助于登录系统将用户重新定向到他想要的位置 .

login?next=my-redirect-url

为了保护我的组件,我在所有组件中都使用了装饰器 @CanActivate(isUserAuthenticated) . isUserAuthenticated 函数如下:

function isUserAuthenticated(
    prevInstr: ComponentInstruction, 
    nextInstr: ComponentInstruction
): boolean {
    const authService = injector.get(AuthService);
    const router = injector.get(Router);
    if(authService.isLoggedIn()) {
        return true;
    } else {
        router.navigate(["/Login", {next: nextInstr.urlPath}]);
        return false;
    }
}

此方法无法正常工作,因为 nextInstrurlPath 属性未显示"complete" url(例如,它缺少查询参数) .

有没有办法从像 nextInstr 这样的 ComponentInstruction 实例构建完整的URL?

2 回答

  • 14

    是的有一种方法:

    let url = router.generate(['./Login', {next: nextInstr.urlPath}]).toRootUrl();
    

    让我们说下面的结构示例取决于routeconfig:

    login?next=my-redirect-url
    

    然后使用navigateByUrl导航到以下url

    router.navigateByUrl('/' + url);
    

    我用我的例子测试了它,你可以在图像上看到结果:

    let instruction = router.generate(['./Country', {country: 'de', a: 1, b: 2}]);
    console.log(instruction, instruction.toRootUrl());
    

    enter image description here

  • 8

    另一种方法(没有使用@ angular / router 3.0.0使用查询参数)来实现在认证后重定向到原始请求资源的相同要求是使用 RouterStateSnapshot.url ,这是一个包含用户请求的资源的url的字符串 . 在认证尝试失败后将用户重定向回登录表单之前,在 CanActivate 挂钩内,从 RouterStateSnapshot.url 获取请求的URL并将其存储在您的登录功能可访问的变量中 . 当用户成功登录时,只需重定向到存储的URL即可 . 这是我的例子:

    //GaurdService - implements CanActivate hook for the protected route
    
    import { Injectable } from '@angular/core';
    import { CanActivate, Router, RouterStateSnapshot } from '@angular/router';
    import { AuthService } from './auth.service';
    
    @Injectable()
    export class GuardService implements CanActivate {
        constructor( private router: Router, private authService: AuthService ) {}
    
        canActivate(state: RouterStateSnapshot): boolean {
            let url: string = state.url;
            return this.checkLogin(url);
        }
    
        checkLogin(url: string): boolean {
            if (this.authService.loggedIn()) { return true; }
            this.authService.redirectUrl = url; // set url in authService here
            this.router.navigate([ '/login' ]); // then ask user to login
            return false;
        }
    
    }
    

    执行登录的My AuthService(下面)将在成功登录时将用户重定向到最初请求的资源 .

    import { Injectable, Inject } from '@angular/core';
    import { tokenNotExpired } from 'angular2-jwt';
    import { Router } from '@angular/router';
    import { Headers, Http, Response, RequestOptions  } from '@angular/http';
    import { Observable } from 'rxjs';
    import './../rxjs-operators';
    
    const API_URL: string = '';
    
    @Injectable()
    export class AuthService {
        public redirectUrl: string = ''; //Here is where the requested url is stored
    
    constructor( @Inject('API_URL') private apiURL: string, private router: Router, private http: Http ) {}
    
        public loggedIn(): boolean {
            return tokenNotExpired('token');
        }
    
        public authenticate(username: string, password: string)  {
            let body: string = JSON.stringify({ un: username, pw: password});
            let headers: Headers = new Headers({ 'Content-Type': 'application/json' });
            let options: RequestOptions = new RequestOptions({ headers: headers });
            return this.http.post(this.apiURL + '/authenticate', body, options)
                .map(res => res.json())
                .subscribe(res => {
                    localStorage.setItem('token',res.token);
                    this.redirect(); // Redirect to the stored url after user is logged in
                });
    
            .catch(this.handleError);
        }
    
        private redirect(): void {
            this.router.navigate([ this.redirectUrl ]); //use the stored url here
        }
    }
    

    这是您的应用程序在不使用查询参数的情况下记住最初请求的资源的方式 .

    有关详细信息,请参阅angular.io中的示例指南,从"GUARD THE ADMIN FEATURE"部分开始:https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard

    希望这有助于某人 .

相关问题