I have a 'Teams' collection in Firestore. A team document will include a team_users
map field where userID: true
if they are a part of that team.
I have a query in a service that returns and displays all team documents where the logged in user id matches an ID within the team_users
field.
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());
}
What I need to achieve is a route guard that performs the following:
Team A
, but have since left, they should not be able to access this route and should instead be redirected back to the url of /teams
/teams
listing urlNote: A user can be a part of multiple teams. If the user was a part of Team A, B and C and has bookmarks for pages in Team A, but has since left, the route guard should prevent them from accessing any pages that were a part of Team A, but still allow access to Team B and C pages.
Does this mean that:
Any help would be greatly appreciated.
A user is on /teams page displaying teams (You don't need a guard on this route). When a user clicks on one of the teams navigate to /teams/teamID (Now this route needs a guard to prevent a user that doesn't belong to teamID from accessing it. To set the guard do this:
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)); }
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)); }
You can do it this way: 1. Make an Auth guard, let say it "AG". 2. In this "AG", make a REST call to your backend. Sending the bookmark ID, USer ID, Current Team Id. "AG" will get triggered on route change where-ever applied. 3. This REST call will compare the current team Id and the Team Id saved with that Bookmark(Assumption: Bookmark table has the column of Team Id as foreign key). 4. So when the service return TRUE/FALSE, then "AG" will know that if it is authorized or not. 5. If it is FALSE, then route user to whatever url.
Example of sample code:
@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;
}
}
Adding the route example:
export const ROUTES: Routes = [
{ path: '', component: Home},
{
path: 'team/{id}',
component: TeamComponent,
canActivate: [AuthGuard]
},
{ path: '**', redirectTo: '' }
];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.