我在应用程序中有2个警卫,AuthGuard和AccessGuard.AuthGuard按名称建议保护所有页面,并将会话对象存储在GlobalService中,AccessGuard依赖于AuthGuard在GlobalService中存储的会话对象中的一些访问数据.
当AuthGuard返回Observable然后同时执行AccessGuard以检查尚未到达的会话对象并且代码中断时,会出现问题.有没有其他方法可以限制AccessGuard的执行,直到会话对象到达或任何其他工作来打破这种竞争条件?
#Note我没有将AccessGuard逻辑合并到AuthGuard,因为只有部分路由需要检查才能访问,而所有其他需要身份验证.例如,"用户管理"和"仪表板"之外的所有人都可以访问"帐户"页面和"数据库"页面,这些参数需要来自会话对象的外部访问参数
export const routes: Routes = [
{
path: 'login',
loadChildren: 'app/login/login.module#LoginModule',
},
{
path: 'logout',
loadChildren: 'app/logout/logout.module#LogoutModule',
},
{
path: 'forget',
loadChildren: 'app/forget/forget.module#ForgetModule',
},{
path: 'reset',
loadChildren: 'app/reset/reset.module#ResetModule',
},
path: 'pages',
component: Pages,
children: [
{ path: '', redirectTo: 'db', pathMatch: 'full' },
{ path: 'db', loadChildren: 'app/pages/db/db.module#DbModule' },
{ path: 'bi', loadChildren: 'app/pages/dashboard/dashboard.module#DashboardModule', canActivate:[AccessableGuard] },
{ path: 'account', loadChildren: 'app/pages/account/account.module#AccountModule' },
{ path: 'um', loadChildren: 'app/pages/um/um.module#UserManagementModule', canActivate:[AccessableGuard] },
],
canActivate: [AuthGuard]
}
];
export …Run Code Online (Sandbox Code Playgroud) 我正在CanDeactivate其中一个主要组件中实现功能。为了测试它,我使它始终返回,false因此路线一定不能更改。
在此CanDeactivate实现中,对的调用component.canDeactivate()返回一个解析为false的Promise:
@Injectable()
export class CanDeactivateNewRecord implements
CanDeactivate<NewRecordComponent> {
canDeactivate(
component: NewRecordComponent,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState: RouterStateSnapshot ):
Observable<boolean>|Promise<boolean>|boolean {
return component.canDeactivate();
}
}
Run Code Online (Sandbox Code Playgroud)
这是带有模块路由定义的片段:
const recordsRoutes: Routes = [
{
path: 'nou',
component: NewRecordComponent,
canDeactivate: [CanDeactivateNewRecord]
},{
path: ':id',
component: RecordComponent
}
];
Run Code Online (Sandbox Code Playgroud)
当我使用from back的服务方法导航到上一页时,有两种不同的情况:Location@angular/common
即使以前的位置是由路由器管理的,调用location.back()足够的次数(与通过应用程序导航的历史记录的长度一样多),也会使导航返回到启动应用程序之前的页面。
这怎么了
我正在尝试在应用程序启动之前加载一些数据.我需要这样做的原因是因为某些菜单基于某些用户条件限制了访问,例如,基于用户位置.
因此,如果用户还没有位置或者它的位置未能访问某些视图,我需要阻止它.
我尝试使用Angular Resolve方法,但没有成功,这就是我所做的:
解决警卫
// The apiService is my own service to make http calls to the server.
@Injectable()
export class AppResolveGuard implements Resolve<any> {
constructor(
private _api: ApiService,
private _store: Store<IStoreInterface>,
) { }
resolve(): any {
return this._api.apiGet('loadData').subscribe(response => {
this._store.dispatch({
type: USER_FETCH_DATA,
payload: response.usuario
});
return response;
});
}
}
Run Code Online (Sandbox Code Playgroud)
路由
export const routing = [
{
path: '', component: AppComponent, canActivateChild: [AuthGuard], resolve: {app: AppResolveGuard},
children: [
{ path: 'home', component: HomeComponent },
{ path: …Run Code Online (Sandbox Code Playgroud) 这是我的静态登录服务
login(email: string, password: string) {
debugger;
const user = {
username: email,
password: password,
};
if (email === "admin" && password === "admin") {
localStorage.setItem("currentUser", JSON.stringify(user));
}
if (localStorage.getItem("currentUser")) {
// logged in so return true
return user;
} else {
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
我的身份验证服务
export class AuthGuard implements CanActivate {
constructor(private router: Router) {
}
isAuthenticated(): boolean{
if (localStorage.getItem("currentUser")) {
return true;
}
else{
return false;
}
}
canActivate(): boolean {
if (!this.isAuthenticated()) {
this.router.navigate(['login']);
return false; …Run Code Online (Sandbox Code Playgroud) 目前,在 Angular 中,您可以通过对其中一个父路由应用路由器保护来限制对所有子路由的访问:
export const routes: Routes = [
{
path: 'my-account',
canActivate: [IsUserLoggedIn],
children: [{
path: 'settings',
component: SettingsComponent
}, {
path: 'edit-profile',
component; EditProfileComponent
}]
}
];
Run Code Online (Sandbox Code Playgroud)
这有助于避免canActivate在每条路线中重复守卫。但是现在当我想在my-account应该公开访问的情况下引入第三条路线时会发生什么?例如,也许my-account/help每个人都应该能够访问一个可公开访问的帮助页面,即使他们没有登录:
}, {
path: 'help',
component: HelpComponent,
// Somehow make exception to canActivate guard above
}, {
Run Code Online (Sandbox Code Playgroud)
是否有一种干净的方法可以做到这一点,或者是唯一的方法来破坏路由的组织并将路由器保护手动应用于每个子路由,除了“帮助”页面?
我需要制作一个简单的确认窗口,我看到了很多关于如何使用额外操作来完成的示例(例如等到表单的文件上传不是字段)。但是我只需要创建一个带有默认文本的默认确认窗口(如下图所示),以便在用户想要离开当前页面时显示它。而且我无法完全理解我应该在处理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 7中建立一个简单的canDeactivate保护,并且我尝试了许多在线教程中的代码,但是它们都产生相同的错误:
“类型'CanDeactivate'不是通用的。”
我究竟做错了什么?除了出现相同问题的另一个2年未解答的问题,我什至在任何Google匹配中都找不到此错误。
在这里查看代码:
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { CanDeactivate } from '@angular/router/src/utils/preactivation';
export interface CanDeactivateComponent {
canDeactivate: () => Observable<boolean> | boolean;
}
@Injectable()
export class CanDeactivateGuard implements CanDeactivate<CanDeactivateComponent> {
canDeactivate(component) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
Run Code Online (Sandbox Code Playgroud) 如何从父路由的守卫重定向到子路由,同时保护子路由不被直接访问*?
绝对导航的问题,当导航到子路由时,父组件上的守卫会在循环中再次调用。
相对导航的问题在于守卫正在保护父路线,因此还没有激活的路线可以相对导航。此外,这可能不会保护子路由。也许同样的守卫也可以与子路由或 CanActivateChildren 一起使用。
Stackblitz 示例:https ://stackblitz.com/edit/angular-qbe2a7
路线
const appRoutes: Routes = [
{
path: 'foo',
component: FooComponent,
canActivate: [ RedirectionGuard ],
children: [
{
path: 'foo-child',
component: FooChildComponent
}
]
}
];
Run Code Online (Sandbox Code Playgroud)
守卫中的 canActivate()
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean>|Promise<boolean>|boolean {
console.log('guard: ', route, state, this.route);
// idea: create own ActivatedRoute and give it the values from ActivatedRouteSnapshot which knows about 'foo/'
const foo: ActivatedRoute = new ActivatedRoute();
console.log(foo);
// Error: Cannot …Run Code Online (Sandbox Code Playgroud) 我正在尝试Angular2+使用来自共享服务的 Observable创建一个路由保护,该服务保存当前用户角色的字符串值。
问题显然在于将我的注意力从 Promises 转移到 Observables。
到目前为止,我所做的都是基于启发式和尝试错误的方法,但我通过杀死浏览器来解决问题感谢 danday74
.
借助相当于promise.then()的RxJS 序列?我已经将我想做的事情翻译成这个链:
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | boolean {
return this.auth.isRoleAuthenticated(route.data.roles)
.mergeMap((isRoleAuthenticated: boolean) => {
return isRoleAuthenticated ? Observable.of(true) : this.auth.isRole(Roles.DEFAULT_USER);
})
.do((isDefaultUser: boolean) => {
const redirectUrl: string = isDefaultUser ? 'SOMEWHERE' : 'SOMEWHERE_ELSE';
this.router.navigate([redirectUrl]);
})
.map((isDefaultUser: boolean) => {
return false;
});
}
Run Code Online (Sandbox Code Playgroud)
如果 ,如何停止可观察链的进一步传播isRoleAuthenticated = true?如果满足此类条件,我需要返回该布尔值,并确保.do之后不调用运算符块。
限制是必须从canActivate警卫返回布尔值。
observable rxjs angular angular-router-guards angular-observable
我正在 Angular 15.2.9 中实现一个功能性路由器防护,它检查用户是否登录。如果不是这种情况,防护应该返回 或falsea UrlTree(即重定向到登录页面),具体取决于参数redirectToLogin: boolean。
我正在使用类似于本文中的功能路由防护的工厂函数:
\nexport const isLoggedIn = (redirectToLogin: boolean): CanActivateFn => {\n return (next: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {\n const isLoggedIn = !!inject(CookieService).check(\'some_cookie\');\n\n if (isLoggedIn) return true;\n if (!isLoggedIn && !redirectToLogin) return false;\n\n const redirectUrl = inject(Router).createUrlTree([\'user\', \'sign_in\'], {\n queryParams: { next: encodeURIComponent(`/${next.url.join(\'/\')}`) },\n queryParamsHandling: \'merge\',\n });\n return redirectUrl;\n };\n};\nRun Code Online (Sandbox Code Playgroud)\n它的工作原理与预期一致,但我无法为其编写规范:
\n let cookieServiceSpy;\n let activatedRouteSnapshot;\n\n beforeEach(() => {\n cookieServiceSpy = jasmine.createSpyObj<CookieService>([\'check\']);\n …Run Code Online (Sandbox Code Playgroud) typescript angular-routing angular angular-router-guards angular-router