我在尝试浏览不同的路线时遇到了问题.
我有两个不同的路线模块.
app.routes.ts:
仅包含LoginPage
:
export const routes: Routes = [
{
path: 'login',
component: LoginPageComponent,
canActivate: [PreventLoggedInAccess]
},
{
path: '',
redirectTo: 'login',
pathMatch: 'full'
},
{
path: '**',
redirectTo: 'login'
}
];
export const Routing: ModuleWithProviders =
RouterModule.forRoot(routes, { useHash : true });
Run Code Online (Sandbox Code Playgroud)
使用PreventLoggedInAccess.canActivate,如果用户已经登录,则将其重定向到具有/app
前缀和子路由的登录部分home
.它被定义为:
canActivate(): boolean {
if (!this._authService.isAuthenticated()) {
return true;
}
this._router.navigate(['/app/home']);
return false;
}
Run Code Online (Sandbox Code Playgroud)
pages.routes.ts:
包含/app
仅在用户登录时才可访问的所有子路由.这可以通过以下方式实现AuthGuardService.canActivateChild
:
export const pageRoutes: Routes = [ …
Run Code Online (Sandbox Code Playgroud) typescript angular-routing angular angular-router-guards angular-router
在我的一些角度路线防护中,我想设置"下一个"路径,在成功登录后重定向到.
因此,oridinary guard canActivate
功能签名如下所示:
public canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | boolean {
// ...blah
return true;
}
Run Code Online (Sandbox Code Playgroud)
该route
参数是ActivatedRouteSnapshot的实例.
以前要获得"下一个"URL我只是从它获得它route.url
.只要没有儿童路线,这种方法就可以了.
我的示例URL是/search/advanced?query_hash=1221d3b57f5616ee16ce70fdc78907ab
,其中advanced
是a的子路由search
.
可以找到子路由route.children
,但迭代这些子路径(特别是可能有多个级别),并且这种方式组合URL似乎很尴尬和丑陋.
我感兴趣的是包含在route._routerState.url
属性中(是一个字符串,位于下图中的底部),但它是一个"私有"变量.
我错过了什么吗?如何才能优雅地从中获取完整的(带有儿童路径)网址ActivatedRouteSnapshot
?Angular版本是5.1.
我有一点泡菜.我正在使用Route guard(实现CanActivate
接口)来检查用户是否被授予访问特定路由的权限:
const routes: Routes = [
{
path: '',
component: DashboardViewComponent
},
{
path: 'login',
component: LoginViewComponent
},
{
path: 'protected/foo',
component: FooViewComponent,
data: {allowAccessTo: ['Administrator']},
canActivate: [RouteGuard]
},
{
path: '**',
component: ErrorNotFoundViewComponent
}
];
Run Code Online (Sandbox Code Playgroud)
现在它可以很好地保护'/ protected/foo'路由不被激活,但我想告诉用户他试图访问的路由是禁止的(类似于你可能从服务器获得的403 Forbidden).
问题:
如何向用户显示此特殊错误视图,而不将其重定向到错误路径哪个接缝是我找到的众多来源的首选选项?
而且如何在RouteGuard
没有实际加载禁止路线的情况下仍然使用我,因为如果我检查我的内部访问FooViewComponent
并显示不同的视图它首先会失败点RouteGuard
.
理想情况下,我想让我RouteGuard
不仅在canActivate()
方法中返回false ,而且还完全用say替换组件ErrorForbiddenViewComponent
.但我不知道该怎么做,或者事件是否可能.任何替代品?
这就是我的护卫队现在的样子:
import {Injectable} from '@angular/core';
import {Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {AuthService} from '../services/auth.service';
@Injectable()
export …
Run Code Online (Sandbox Code Playgroud) 我遇到了以下问题:当我导航到或通过浏览器刷新时,通过AuthGuard服务保护的个人部分被加载两次.如果我提供任何URL,它第二次剥离URL的查询参数.这是我的app路由器配置:
const routes: Routes = [
{
path: 'search',
redirectTo: '',
pathMatch: 'full'
},
{
path: '',
component: BookmarksComponent
},
{
path: 'tagged/:tag',
component: TagComponent
},
{
path: 'about',
component: AboutComponent
},
{
path: 'personal',
loadChildren: 'app/personal/personal-bookmarks.module#PersonalBookmarksModule'
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Run Code Online (Sandbox Code Playgroud)
和子路由器配置
@NgModule({
imports: [RouterModule.forChild([
{
path: '',
component: PersonalBookmarksComponent,
canActivate: [AuthGuard],
children: [
{
path: '',
component: PersonalBookmarksListComponent
},
{
path: 'new',
component: NewPersonalBookmarkFormComponent
},
{
path: …
Run Code Online (Sandbox Code Playgroud) 如何通过 DI 使用 Angular 16 中最新的 CanActivateFn?
最近的 Angular 16 使用函数而不是类来实现 canactivate 功能。这是我下面的代码。如何添加通常位于函数构造函数中的 DI?
CanActivateFn函数代码:
export const authGuard: CanActivateFn = (
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) => {
return inject(TokenService).authenticated.pipe(
take(1),
map((status) => {
console.log('auth status: ', status);
if (!status) {
return inject(Router).createUrlTree(['/login']);
}
return true;
})
);
};
Run Code Online (Sandbox Code Playgroud)
路线设置:
const routes: Routes = [
{
path: '',
component: DefaultComponent,
canActivate: [authGuard],
children: [
{
path: '',
component: DashboardComponent,
data: { title: 'My Dashboard' },
},
]
Run Code Online (Sandbox Code Playgroud) 我将所请求的Url保存在localstorage中,重定向到身份服务器,这个重定向回我的根URL,然后我想导航到之前保存的URL.
我在守卫中保存网址:
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> {
const hasAccessToken$ = Observable.of(this.oAuthService.hasValidAccessToken());
const setRedirect$ = hasAccessToken$
.filter(isAllowed => !isAllowed)
.do(() => localStorage.setItem('login.redirect', state.url)) // save requested url for later redirect
.do(() => this.oAuthService.initImplicitFlow());
setRedirect$.subscribe();
return hasAccessToken$;
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试在我的app.component.ts中重定向:
ngOnInit() {
this.oAuthService.tryLogin({ onTokenReceived: () => this.redirect() }); // try to parse token from url
}
private redirect() {
const url = localStorage.getItem('login.redirect');
console.log(url);
this.router.navigateByUrl(url);
}
Run Code Online (Sandbox Code Playgroud)
我的路由看起来像这样:
const routes: Routes = [
{
path: 'files',
loadChildren: './folder-page/folder-page.module#FolderPageModule',
canActivate: [AuthGuard]
},
{ …
Run Code Online (Sandbox Code Playgroud) 我有一个带有延迟加载模块的 Angular 4.3.6 应用程序。这是一个部分根路由器:
const routes: Routes = [
{ path: '', redirectTo: 'fleet', pathMatch: 'full' },
{
path: '',
component: AppComponent,
canActivate: [AuthenticationGuard],
children: [
{
path: 'fleet',
loadChildren: "./modules/fleet.module",
canActivate: [AuthenticationGuard]
},
{
path: 'password/set',
loadChildren: "./modules/chooseNewPassword.module",
canActivate: [ChoosePasswordGuard]
}
]
}
]
// Exports RouterModule.forRoot(routes, { enableTracing: true });
Run Code Online (Sandbox Code Playgroud)
这两个示例模块中的我的子路由器:
舰队:
RouterModule.forChild([
{
path: '',
component: FleetComponent,
canActivate: [AuthenticationGuard]
}
]);
Run Code Online (Sandbox Code Playgroud)
选择新密码:
RouterModule.forChild([
{
path: '',
component: ChooseNewPasswordComponent,
canActivate: [ChoosePasswordGuard]
}
]);
Run Code Online (Sandbox Code Playgroud)
该AuthenticationGuard
调用一个方法,看起来像这样:
return this.getUserSession().map((userSession: …
Run Code Online (Sandbox Code Playgroud) 我有这个界面,我用来阻止用户离开页面
export interface ComponentCanDeactivate {
canDeactivate: () => boolean;
}
@Injectable()
export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
canDeactivate(component: ComponentCanDeactivate): boolean {
return component.canDeactivate() ?
//code : //more code
}
}
Run Code Online (Sandbox Code Playgroud)
在我的一个组件中,我有以下代码
export class DashboardComponent implements ComponentCanDeactivate{
@HostListener('window:beforeunload')
canDeactivate(): boolean {
return !this.isDirty;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是来自PendingChangesGuard的我的组件 - >(component:ComponentCanDeactivate)总是为空,所以我得到一个错误说
无法调用null的canDeactivate()
我的路由也有这个设置
path: 'dashboard',
canDeactivate: [PendingChangesGuard],
loadChildren: './views/dashboard/dashboard.module#DashboardModule'
Run Code Online (Sandbox Code Playgroud)
谁能告诉我我做错了什么?
在我当前的注销呼叫中,我有这样的事情:
getLogoutConfirmation(){
// get confirmation in modal and perform logout
// redirect to login page
}
Run Code Online (Sandbox Code Playgroud)
问题是,当执行注销并调用重定向到登录时,会在该路由上调用 canDeactivate 防护,但用户已经注销。
那么如何在执行注销之前调用 canDeactivate 守卫并在用户不想离开时取消注销操作。
谢谢。
我需要制作一个简单的确认窗口,我看到了很多关于如何使用额外操作来完成的示例(例如等到表单的文件上传不是字段)。但是我只需要创建一个带有默认文本的默认确认窗口(如下图所示),以便在用户想要离开当前页面时显示它。而且我无法完全理解我应该在处理before unload
事件中证明什么逻辑。
如果它重复了一些问题,我最近很抱歉,但是,我没有找到任何解决方案。所以我有:
例子.guard.ts
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | boolean;
}
@Injectable()
export class ExampleGuard implements CanDeactivate<CanComponentDeactivate> {
constructor() { }
canDeactivate(component: CanComponentDeactivate): boolean | Observable<boolean> {
return component.canDeactivate() ?
true :
confirm('message'); // <<< does confirm window should appear from here?
}
}
Run Code Online (Sandbox Code Playgroud)
示例.component.ts
export class ExampleComponent implements CanComponentDeactivate {
counstructor() { }
@HostListener('window:beforeunload', ['$event'])
canDeactivate($event: any): Observable<boolean> | boolean {
if (!this.canDeactivate($event)) {
// what should I do here?
}
}
} …
Run Code Online (Sandbox Code Playgroud) angular ×9
typescript ×2
angular16 ×1
angular5 ×1
angular6 ×1
javascript ×1
keycloak ×1
lazy-loading ×1
oauth-2.0 ×1