我使用的是角度2.4版本和路由器版本“^ 3.4.10”。
我正在尝试使用auth guard服务处理重定向网址。
当用户点击url'domain / assignment / 3 / detail'并且如果用户未登录,则用户重定向到“域/登录”页面。 当用户成功登录系统,然后重定向到“domain / assignment / 3 / detail”用户尝试访问的上一个URL。
我在分配模块上实现了CanLoad guard。因此,当用户尝试访问url'domain / assignment / 3 / detail'并且如果用户未登录时,url将存储到authservice(this.authService.redirectUrl)的redirectUrl属性中。
所以这就是我的问题。我无法获得用户点击的网址的完整路径。 我在CanLoad后卫中获得“任务”而非“任务/ 3 /细节”。 如何获得完整路径,以便我可以将用户重定向到CanLoad后卫内的正确路径。
CanLoad:
canLoad(route: Route): boolean {
let url = `/${route.path}`; // here i got url path 'assignment' instead 'assignment/3/detail'
return this.checkLogin(url);
}
主要路由 app.routes.ts
const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent},
{
path: 'assignment',
loadChildren: './assignment/assignment.module#AssignmentModule',
canLoad: [AuthGuard]
},
{ path: '**', redirectTo: '', pathMatch: 'full' }];
分配路由: assignment-routing.ts
const assignmentRoutes: Routes = [
{
path: '',
component: AssignmentComponent,
canActivate: [AuthGuard]
children: [
{
path: '',
canActivateChild: [AuthGuard],
children: [
{
path: ':assignmentId/detail', component: AssignmentDetailComponent,
canActivate: [AuthGuard]
}
]
}]
}];
AuthGuard:auth-gurad.service.ts
import { Injectable } from '@angular/core';
import {
CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot,
CanActivateChild,
NavigationExtras,
CanLoad, Route
} from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
constructor(private authService: AuthService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url;
return this.checkLogin(url);
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.canActivate(route, state);
}
canLoad(route: Route): boolean {
let url = `/${route.path}`; // here i got url path 'assignment' instead 'assignment/3/detail'
return this.checkLogin(url);
}
checkLogin(url: string): boolean {
if (this.authService.isLoggedIn) {
if(this.authService.redirectUrl!=null){
let redirectUrl = this.authService.redirectUrl;
this.authService.redirectUrl = null;
this.this.router.navigate([redirectUrl]);
}
return true;
}
// Store the attempted URL for redirecting
this.authService.redirectUrl = url;
// Navigate to the login page
this.router.navigate(['/login']);
return false;
}
}
答案 0 :(得分:4)
我有同样的问题。这些问题是相关的
他们甚至有一个关于此的公开公关尚未合并
现在的解决方法似乎是用canLoad
替换canActivate
方法,在那里你可以访问完整路径,当然不好的是你正在加载模块
编辑:同样适用于分配路由,无需为每个子路由调用canActivate
。在父路线上定义它应该为所有子路线应用保护。
答案 1 :(得分:4)
如果您查看canLoad method的签名,则还有第二个参数segments
,可用于生成网址。
canLoad(route: Route, segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean
您可以使用以下代码生成完整路径:
canLoad(route: Route, segments: UrlSegment[]): boolean {
const fullPath = segments.reduce((path, currentSegment) => {
return `${path}/${currentSegment.path}`;
}, '');
console.log(fullPath);
}
注意:通过这种方法,您将获得完整路径,但不会获得任何查询参数。
答案 2 :(得分:2)
还有另一个临时解决方法,而不是用canLoad
替换canActivate
:
您可以通过redirectUrl = location.pathname
存储网址,然后通过this.router.navigateByUrl(redirectUrl);
重定向。当然,如果您使用子路径(如domain
),则必须稍微调整pathname
。
答案 3 :(得分:2)
在Angular 9中,以下reply为我服务。
我的代码
export class AuthGuard implements CanLoad {
constructor(private router: Router, private loginService: LoginService) { }
canLoad( ): Observable<boolean> | Promise<boolean> | boolean {
if (this.loginService.isLoggedIn()) return true;
this.router.events.pipe(first(_ => _ instanceof NavigationCancel)).subscribe((event: NavigationCancel) => {
this.router.navigate(['/login'], {
queryParams: {
redirectTo: event.url
}
});
});
return false;
}
答案 4 :(得分:0)
这个reply在github问题上的解决方法对我来说非常有效。
export class AuthnGuard implements CanLoad {
constructor(private authnService: AuthnService, private router: Router) { }
canLoad( ): Observable<boolean> | Promise<boolean> | boolean {
const navigation = this.router.getCurrentNavigation();
let url = '/';
if (navigation) {
url = navigation.extractedUrl.toString();
}
this.authnService.storeRedirectUrl(url);
答案 5 :(得分:0)
可用信息
this.router.getCurrentNavigation().extractedUrl