Dav*_*eto 12 angular2-routing angular
我正在使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法不起作用,因为它的urlPath属性nextInstr没有显示"完整"的URL(例如它缺少查询参数).
有没有办法从ComponentInstruction像这样的实例构建完整的URL nextInstr?
nth*_*xis 15
另一种方法(没有使用@ angular/router 3.0.0使用查询参数)来实现在使用身份验证后重定向到原始请求资源的相同要求RouterStateSnapshot.url,这是一个包含用户请求的资源的url的字符串.在失败的身份验证尝试失败后将用户重定向到您的登录表单之前,请在CanActivate钩子内部获取请求的URL RouterStateSnapshot.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;
}
}
Run Code Online (Sandbox Code Playgroud)
执行登录的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
}
}
Run Code Online (Sandbox Code Playgroud)
这就是您的应用程序如何记住最初请求的资源而不使用查询参数.
有关详细信息,请参阅angular.io上的示例指南,从"GUARD THE ADMIN FEATURE"部分开始:https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
希望这有助于某人.
是的有一种方法:
let url = router.generate(['./Login', {next: nextInstr.urlPath}]).toRootUrl();
Run Code Online (Sandbox Code Playgroud)
让我们根据routeconfig说明以下结构示例:
login?next=my-redirect-url
Run Code Online (Sandbox Code Playgroud)
然后使用navigateByUrl导航到以下url
router.navigateByUrl('/' + url);
Run Code Online (Sandbox Code Playgroud)
我用我的例子测试了它,你可以在图像上看到结果:
let instruction = router.generate(['./Country', {country: 'de', a: 1, b: 2}]);
console.log(instruction, instruction.toRootUrl());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14626 次 |
| 最近记录: |