Angular2 Перенаправление После Входа

Я создаю системы аутентификации в angular2 с мыслью, что если пользователь не прошел проверку подлинности пытается перешел в "защищенный" url, система перенаправит пользователя на страницу входа ставя в URL запроса параметр называется "рядом", которые помогут входа в систему, перенаправить пользователя туда, где он хотел быть на первом месте.

login?next=my-redirect-url

чтобы защитить мои компоненты, я использую декоратор @CanActivate(isUserAuthenticated) во всех из них. The это что-то вроде:

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

этот подход не работает, потому что urlPath свойства nextInstr не показывает "полный" url (например, ему не хватает параметров запроса).

есть ли способ построить полный url-адрес из ComponentInstruction примеру nextInstr?

2 ответов


Да есть способ:

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


другой способ (без использования параметров запроса с помощью @angular/router 3.0.0) для достижения того же требования перенаправления на исходный запрошенный ресурс после аутентификации-использовать RouterStateSnapshot.url, которая представляет собой строку, содержащую url ресурса, запрошенного пользователем. Перед перенаправлением пользователя обратно в форму входа после неудачной попытки аутентификации, внутри CanActivate крюк, получить запрошенный url от RouterStateSnapshot.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;
    }

}

мой 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 начиная с "охранять администратора Раздел" : https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard

надеюсь, это кому-то поможет.