Angular Route Guard 基于集合查询结果
Angular Route Guard based on collection query result
我在 Firestore 中有一个 'Teams' 集合。团队文档将包含一个 team_users
映射字段,其中 userID: true
如果他们是该团队的一部分。
我在服务中有一个查询,returns 并显示所有团队文档,其中登录的用户 ID 与 team_users
字段中的 ID 匹配。
getTeamsList(user_id: string) {
this.teamsCollection = this.afs.collection<any>(`teams`, ref => ref.where(`team_users.${user_id}`, "==", true))
this.teams = this.teamsCollection.snapshotChanges().pipe(
map(actions => actions.map(a => {
const data = a.payload.doc.data();
const id = a.payload.doc.id;
return { id, ...data };
}))
).pipe(shareReplay());
}
我需要实现的是执行以下操作的路由守卫:
- 防止用户访问他们不属于/不属于的团队。例如,如果用户在
Team A
时有一个文档书签,但后来离开了,他们不应该能够访问此路由,而是应该被重定向回 url /teams
- 如果用户不属于任何团队(集合查询不产生任何结果),则无法访问
/teams
列表中的部分路由 url
注意:一个用户可以是多个团队的一员。如果用户是 A、B 和 C 团队的一部分,并且拥有 A 团队页面的书签,但已经离开,则路由守卫应该阻止他们访问属于 A 团队的任何页面,但仍然允许访问团队 B 和 C 页面。
这是否意味着:
- 我的应用程序中的每个 URL 都需要这个守卫?
- 我的应用程序中的每个 URL 都需要包含团队 ID?
如有任何帮助,我们将不胜感激。
你可以这样做:
1.做一个Auth guard,说出来"AG"。
2. 在此 "AG" 中,对您的后端进行 REST 调用。发送书签 ID、用户 ID、当前团队 ID。 "AG" 将在任何应用的路线更改时触发。
3. 此 REST 调用将比较当前团队 ID 和使用该书签保存的团队 ID(假设:书签 table 将团队 ID 列作为外键)。
4、所以当服务returnTRUE/FALSE时,那么"AG"就会知道是否授权了。
5. 如果为 FALSE,则将用户路由到 url.
示例代码示例:
@Injectable()
export class AuthGuardService implements CanActivate
{
constructor(public auth: AuthService, public router: Router) {}
canActivate(): boolean
{
if (!this.auth.isAuthenticated()) {
this.router.navigate(['team']);
return false;
}
return true;
}
}
添加路线示例:
export const ROUTES: Routes = [
{ path: '', component: Home},
{
path: 'team/{id}',
component: TeamComponent,
canActivate: [AuthGuard]
},
{ path: '**', redirectTo: '' }
];
一位用户正在 /teams 页面上显示团队(这条路线不需要守卫)。当用户点击其中一个团队时,导航到 /teams/teamID(现在这条路线需要一个守卫来防止不属于 teamID 的用户访问它。要设置守卫,请执行以下操作:
- 编写一个函数来检查 firestore 上的用户是否是团队成员。
isTeamMember(userId: string, teamId: string): Observable < Boolean > {
return this.firestore.doc < any > (`teams/${teamId}`).snapshotChanges().pipe(
map(value => value.payload.data().team_users[userId] === true));
}
- 调用您的 Guard 中的函数(CanActivate 是这样实现的)。请记住注入包含您当前用户的 service/store 并从 Url 检索 teamId。 2 用于调用 firestore
上的函数
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable < boolean > | Promise < boolean > | boolean {
return this.firestoreService.isTeamMember(userIdFromWhereYouStoreYourCurrentUser, teamIdFromTheCurrentUrl).pipe(map(isTeamMember => {
if (isTeamMember) {
return true;
} else {
//Add your not team member logic here, eg Stay in the current route, may be show an error message
return false;
}
}),
take(1));
}
我在 Firestore 中有一个 'Teams' 集合。团队文档将包含一个 team_users
映射字段,其中 userID: true
如果他们是该团队的一部分。
我在服务中有一个查询,returns 并显示所有团队文档,其中登录的用户 ID 与 team_users
字段中的 ID 匹配。
getTeamsList(user_id: string) {
this.teamsCollection = this.afs.collection<any>(`teams`, ref => ref.where(`team_users.${user_id}`, "==", true))
this.teams = this.teamsCollection.snapshotChanges().pipe(
map(actions => actions.map(a => {
const data = a.payload.doc.data();
const id = a.payload.doc.id;
return { id, ...data };
}))
).pipe(shareReplay());
}
我需要实现的是执行以下操作的路由守卫:
- 防止用户访问他们不属于/不属于的团队。例如,如果用户在
Team A
时有一个文档书签,但后来离开了,他们不应该能够访问此路由,而是应该被重定向回 url/teams
- 如果用户不属于任何团队(集合查询不产生任何结果),则无法访问
/teams
列表中的部分路由 url
注意:一个用户可以是多个团队的一员。如果用户是 A、B 和 C 团队的一部分,并且拥有 A 团队页面的书签,但已经离开,则路由守卫应该阻止他们访问属于 A 团队的任何页面,但仍然允许访问团队 B 和 C 页面。
这是否意味着:
- 我的应用程序中的每个 URL 都需要这个守卫?
- 我的应用程序中的每个 URL 都需要包含团队 ID?
如有任何帮助,我们将不胜感激。
你可以这样做: 1.做一个Auth guard,说出来"AG"。 2. 在此 "AG" 中,对您的后端进行 REST 调用。发送书签 ID、用户 ID、当前团队 ID。 "AG" 将在任何应用的路线更改时触发。 3. 此 REST 调用将比较当前团队 ID 和使用该书签保存的团队 ID(假设:书签 table 将团队 ID 列作为外键)。 4、所以当服务returnTRUE/FALSE时,那么"AG"就会知道是否授权了。 5. 如果为 FALSE,则将用户路由到 url.
示例代码示例:
@Injectable()
export class AuthGuardService implements CanActivate
{
constructor(public auth: AuthService, public router: Router) {}
canActivate(): boolean
{
if (!this.auth.isAuthenticated()) {
this.router.navigate(['team']);
return false;
}
return true;
}
}
添加路线示例:
export const ROUTES: Routes = [
{ path: '', component: Home},
{
path: 'team/{id}',
component: TeamComponent,
canActivate: [AuthGuard]
},
{ path: '**', redirectTo: '' }
];
一位用户正在 /teams 页面上显示团队(这条路线不需要守卫)。当用户点击其中一个团队时,导航到 /teams/teamID(现在这条路线需要一个守卫来防止不属于 teamID 的用户访问它。要设置守卫,请执行以下操作:
- 编写一个函数来检查 firestore 上的用户是否是团队成员。
isTeamMember(userId: string, teamId: string): Observable < Boolean > {
return this.firestore.doc < any > (`teams/${teamId}`).snapshotChanges().pipe(
map(value => value.payload.data().team_users[userId] === true));
}
- 调用您的 Guard 中的函数(CanActivate 是这样实现的)。请记住注入包含您当前用户的 service/store 并从 Url 检索 teamId。 2 用于调用 firestore 上的函数
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable < boolean > | Promise < boolean > | boolean {
return this.firestoreService.isTeamMember(userIdFromWhereYouStoreYourCurrentUser, teamIdFromTheCurrentUrl).pipe(map(isTeamMember => {
if (isTeamMember) {
return true;
} else {
//Add your not team member logic here, eg Stay in the current route, may be show an error message
return false;
}
}),
take(1));
}