Angular2登录后重定向
我正在angular2中创建一个身份验证系统,其思想是,如果未经身份验证的用户尝试导航到“受保护”的url,系统会将用户重定向到登录页面,并在url中输入一个名为“next”的查询参数这将有助于登录系统将用户重定向回他最初想要的位置Angular2登录后重定向,angular,angular2-routing,Angular,Angular2 Routing,我正在angular2中创建一个身份验证系统,其思想是,如果未经身份验证的用户尝试导航到“受保护”的url,系统会将用户重定向到登录页面,并在url中输入一个名为“next”的查询参数这将有助于登录系统将用户重定向回他最初想要的位置 login?next=我的重定向url 为了保护我的组件,我在所有组件中都使用了decorator@CanActivate(isUserAuthenticated)。isUserAuthenticated函数如下所示: 函数是经过用户身份验证的( 说明:组件说明,
login?next=我的重定向url
为了保护我的组件,我在所有组件中都使用了decorator@CanActivate(isUserAuthenticated)
。isUserAuthenticated
函数如下所示:
函数是经过用户身份验证的(
说明:组件说明,
nextInstr:组件指令
):布尔值{
const authService=injector.get(authService);
const router=injector.get(路由器);
if(authService.isLoggedIn()){
返回true;
}否则{
导航([“/Login”,{next:nextInstr.urlPath}]);
返回false;
}
}
这种方法不起作用,因为nextInstr
的urlPath
属性没有显示“完整”的url(例如,它缺少查询参数)
是否有一种方法可以从ComponentInstruction
实例(如nextInstr
)构建完整的url?是的,有一种方法:
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());
实现身份验证后重定向到原始请求资源的相同要求的另一种方法(不使用@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;
}
}
执行登录的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上的示例指南,从“保护管理功能”部分开始:
希望这对某人有所帮助。您看过中的讨论吗?我认为它与您试图实现的目标非常相似。还有一个指向Plunker的链接(我自己还没有仔细查看)。@GünterZöchbauer感谢这个链接,但我已经解决了如何在装饰函数
isUserAuthenticated
中获取注入器的问题。我的问题是如何生成url以在登录后重定向用户。我没有阅读所有细节,但我得到的印象是他们也讨论了查询参数。对不起,太吵了。