Angular: useFactory with injection token - AUTHORIZATION GUARD

PHOTO EMBED

Mon Feb 27 2023 09:31:13 GMT+0000 (Coordinated Universal Time)

Saved by @mtommasi

/*
First create your Service that you want to inject using the custom token
*/

import {tap, first, map} from 'rxjs/operators';

import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from "@angular/router";
import {Observable} from "rxjs";
import {AuthService} from "./auth.service";
import * as _ from 'lodash';
import {Injectable} from "@angular/core";

@Injectable()
export class AuthorizationGuard implements  CanActivate {


    constructor(private allowedRoles:string[],
                private authService:AuthService, private router:Router) {

    }


    canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): Observable<boolean>  {

        return this.authService.user$.pipe(
            map(user => _.intersection(this.allowedRoles, user.roles).length > 0 ),
            first(),
            tap(allowed => {
                if (!allowed) {
                    this.router.navigateByUrl('/');
                }
            }),);


    }

}

/**as you can see the first argument is a string of roles*/
/** Inside the app.module:*/

import {BrowserModule} from '@angular/platform-browser';
import {NgModule, Provider} from '@angular/core';
import {HttpClientModule, HttpClientXsrfModule} from '@angular/common/http';
import {AuthService} from "./services/auth.service";
import {AuthorizationGuard} from "./services/authorization.guard";

//this is the factory function that returns the instance of the Guard:

export function createAdminOnlyGuard(authService:AuthService, router:Router) {
    return new AuthorizationGuard(['ADMIN'], authService, router);
}



@NgModule({
    declarations: [
        AppComponent,

    ],
    imports: [
        BrowserModule,
        HttpClientModule,

    ],
    providers: [
 
        AuthService,
        {
            provide: 'adminsOnlyGuard',
            useFactory: createAdminOnlyGuard,
            deps: [
                AuthService,
                Router
            ]

        }
    ],
    bootstrap: [AppComponent]
})
export class AppModule {

}

//usage :

import {Routes} from '@angular/router';
import {AdminComponent} from "./admin/admin.component";

export const routesConfig: Routes = [
    {
        path: 'admin',
        component: AdminComponent,
        canActivate: ["adminsOnlyGuard"]
    },
];




content_copyCOPY