Angular2 登录后重定向

Angular2 Redirect After Login

我在 angular2 中创建了一个身份验证系统,如果未通过身份验证的用户试图导航到 "protected" 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?

是的,有办法:

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

假设以下结构示例取决于路由配置:

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());

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

//GuardService - 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;
    }

}

执行登录的我的 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/guide/router#guard-the-admin-feature

希望这对某人有所帮助。