Below is the order in which Guard are processed in the following order:
- canDeactivate
- canLoad
- canActivateChild
- canActivate
- resolve
To implement a route guard in Angular, you need to create a guard service that implements a specific guard type provided by Angular. This service will contain a method associated with the guard type. Let's take a look at how to build a guard service:
typescriptimport { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGardService implements CanActivate {
canActivate(): boolean {
// Implement your authentication logic here
// For example, check if the user is logged in and has the necessary roles/permissions
// If the user is authenticated, return true to allow access to the route
// If the user is not authenticated, you can redirect them to the login page or any other route using the Router service and return false
// For demonstration purposes, let's assume the user is already authenticated and has access
return true;
}
}
typescriptimport { AuthGuard } from './auth-guard.service.ts';
// ...
{
path: ':id',
component: CoderevisitedDetailComponent,
resolve: { article: CoderevisitedResolver },
canActivate: [AuthGuard]
}
We imported the AuthGuard from './auth-guard.service.ts'. Then, we define a route configuration object where we specify the path :id, the CoderevisitedComponent as the component to render for that route, and the CoderevisitedResolver for resolving data before activating the route. Additionally, we include the canActivate property with the value [AuthGuard] to indicate that the AuthGuard should be used to guard access to this route.Angular Guard Types
1.canActivate (Guard navigation to a route):
The canActivate guard is triggered when the URL changes to a route that matches the guard. It is commonly used to
The canActivate guard is triggered when the URL changes to a route that matches the guard. It is commonly used to
- limit route access to specific users
- ensure that certain prerequisites are met
You can generate this guard using the Angular CLI, and it can be implemented as follows:
bashng generate guard thecoderevisited/auth
// shorthand - ng g g
thecoderevisited/auth
When you run this command in the terminal, Angular CLI will prompt you to choose the guard type you want to implement, excluding canDeactivate and canLoad guards. After selecting the desired guard type, the CLI will generate the guard file along with its associated testing file.
It's important to note that the generated files will follow the Angular guard template, and you can customize them according to your specific needs.
2. canActivateChild (Guard navigation to a child route):
Similar to canActivate, the canActivateChild guard is used when activating a child route instead of the route itself. It checks criteria before activating a child route, such as
Similar to canActivate, the canActivateChild guard is used when activating a child route instead of the route itself. It checks criteria before activating a child route, such as
- limiting access
- ensuring prerequisites are met
3. canDeactivate (Guard navigation away from a route):
The canDeactivate guard is responsible for checking criteria before leaving a route. It is commonly used to handle scenarios such as
- checking for unsaved changes
- confirming incomplete operations
- alerting the user
Unlike other guard types, canDeactivate requires a generic parameter to identify the component using the guard. Here's an example of how to use it:
typescriptimport { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanDeactivate, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { EditArticleComponent } from './coderevisited.component.ts';
@Injectable({
providedIn: 'root'
})
export class CoderevisitedGuard implements CanDeactivate<EditArticleComponent> {
canDeactivate(
component: CoderevisitedComponent,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot
): boolean | Observable<boolean> | Promise<boolean> {
// Implement your canDeactivate logic here
// For example, check if the user has unsaved changes and prompt for confirmation before leaving the route
// You can access the component, current route, current state, and next state within this method
// For demonstration purposes, let's assume there are no unsaved changes and allow deactivation
return true;
}
}
We imported the CoderevisitedComponent from './coderevisited.component.ts'.
Then, we create the CoderevisitedGuard class that implements the CanDeactivate interface with the CoderevisitedComponent type. The canDeactivate method is implemented to handle the deactivation logic. You can customize this method to check for unsaved changes, prompt for confirmation, or perform any other necessary checks before allowing the deactivation of the component.
Please ensure that you have the correct import path for the CoderevisitedComponent and adjust it accordingly based on its actual location in your project.
The last step is, now add this guard to the route in the module:
typescriptimport { CoderevisitedGuard } from './coderevisited.guard.service.ts';
import { CoderevisitedComponent } from './coderevisited.component.ts';
// ...
{
path: ':id/edit',
component: CoderevisitedComponent,
canDeactivate: [CoderevisitedGuard],
resolve: { article: CoderevisitedResolver }
}
4. canLoad (Prevent asynchronous routing):
The canLoad guard prevents the application from loading an entire module or component lazily (lazy loading) if the user is not authorized. It differs from canActivate as it optimizes the app's performance by preventing the loading of unauthorized modules/components.
Here's an example of its implementation:
typescriptclass UserToken {}
class Permissions {
canLoadChildren(user: UserToken, id: string, segments: UrlSegment[]): boolean {
return true;
}
}
@Injectable()
class CanLoadCoderevisitedArticles implements CanLoad {
constructor(private permissions: Permissions, private currentUser: UserToken) {}
canLoad(route: Route, segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
return this.permissions.canLoadChildren(this.currentUser, route.path, segments);
}
}
Now add this guard to the route in the module:
typescript@NgModule({
imports: [
RouterModule.forRoot([
{
path: 'coderevisited-team-artiles/:id',
component: CoderevisitedTeamArticlesComponent,
canLoad: [CanLoadCoderevisitedArticles]
}
])
],
providers: [CanLoadCoderevisitedArticles, UserToken, Permissions]
})
class AppModule {}
5. resolve (Prefetch data before activating a route):
The resolve guard allows you to fetch data before navigating to a route. It ensures that the component is rendered along with the data, avoiding empty components or the need for spinners.
Example :
typescript@Injectable({
providedIn: 'root'
})
export class CoderevisitedResolver implements Resolve<CoderevisitedComponent> {
constructor(private articlesService: ArticlesService) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<any> | Promise<any> | any {
return this.articlesService.getArticles(route.paramMap.get('id'));
}
}
typescript@NgModule({
imports: [
RouterModule.forRoot([
{
path: 'articles/:id',
component: CoderevisitedComponent,
resolve: {
articles: CoderevisitedResolver
}
}
])
],
exports: [RouterModule]
})
export class AppRoutingModule {}
In the code above, we have the AppRoutingModule class decorated with @NgModule. Within the imports array, we configure the router module using RouterModule.forRoot(). Inside the router configuration, we define a route for the path 'articles/:id'. The CoderevisitedComponent is set as the component to render for this route. We include a resolve property that maps the 'articles' key to the CoderevisitedResolver class. This means that before activating the route, the CoderevisitedResolver will be used to resolve the 'articles' data.
Please make sure to provide the correct import paths for RouterModule, CoderevisitedComponent, and CoderevisitedResolver based on their actual file locations in your project.
In conclusion, Angular Router Guards play a vital role in ensuring the security and access control of your Angular applications. By implementing these guards, you can effectively manage route navigation, protect sensitive areas, and perform necessary checks before activating routes.
Throughout this article, we have explored the different types of Angular Router Guards and provided practical examples to demonstrate their usage. By understanding and applying these guards in your projects, you can create secure and user-friendly Angular applications.
By incorporating Angular Router Guards into your development process, you can elevate your web development skills to new heights. These guards serve as valuable tools for enhancing the security and reliability of your Angular applications. So, don't hesitate to start utilizing and implementing Angular Router Guards today to unlock the full potential of your web development endeavors.
Read more :
No comments:
Post a Comment