Angular Authentication: Role Based Authorization

Поділитися
Вставка
  • Опубліковано 9 лис 2024

КОМЕНТАРІ • 58

  • @MhmmDonuts
    @MhmmDonuts 2 роки тому +3

    This is my first time building a Internet application (im a junior front end dev). Normaly we only do intranet applications but this series has helped me sooooo much to get in touch with JWT Interceptors and a basic login system. THANK YOU SO MUCH!!!!!

  • @zura8635
    @zura8635 3 місяці тому +1

    Great Video! However I have a question... What do you think about sending /get-profile request to the API and storing user data using behaviour subject? Wouldn't that be as good?

    • @CodeShotsWithProfanis
      @CodeShotsWithProfanis  2 місяці тому

      Yes, that would work nicely as well.
      In fact, you can interact with a behaviourSubject (or a signal ;) ) and have this in sync with your storage (localStorage or sessionStorage)

    • @zura8635
      @zura8635 2 місяці тому

      @@CodeShotsWithProfanis thanks for your feedback ❤️

  • @samitdigitalart
    @samitdigitalart 3 роки тому +3

    Excellent, Very simple and straight to the point. Thanks

  • @ThomasBurleson
    @ThomasBurleson 2 роки тому +1

    Nice technique to parse the allowed roles from the access token.

  • @ziadnajami3582
    @ziadnajami3582 Рік тому +1

    Just wants to say thank you, saved my semester ❤

  • @aaelborollosy
    @aaelborollosy 2 роки тому +2

    as usual brief and exactly to the point

  • @cholasimmons
    @cholasimmons Рік тому +1

    Brilliant! What happens when you have several roles that require access? My role setup isn't hierarchical .

    • @CodeShotsWithProfanis
      @CodeShotsWithProfanis  Рік тому

      If the user.roles property has more than one roles and you have to make sure that both roleX and roleY exist in the array, you should make sure to check if all these items exist in the user.roles array.
      Unless I misunderstood your question

  • @saurabhchauhan232
    @saurabhchauhan232 3 роки тому +2

    Fantastic explanation awaiting for many more

  • @SamiullahKhan
    @SamiullahKhan 2 роки тому +2

    Is it necessary to decode the way you did the role info from token, why don't just send the serialised object from server. Personally I don't like accessing info by using index signatures 😜
    In addition I want to learn is it safe to store role in the local storage?
    Otherwise thanks for the video

    • @CodeShotsWithProfanis
      @CodeShotsWithProfanis  2 роки тому

      No it is not necessary to decode the token like I did. If you choose the tokens to be part of the JWT claims, then you have to decode. An alternative would be to have the roles part of the HTTP response and not part of the JWT. In this case you do not have to decode them.
      As of the localStorage, it's OK to persist non sensitive information.

  • @priyankaravichandran851
    @priyankaravichandran851 Рік тому +1

    Great , kindly upload Oauth validations , OKTA like that

  • @felixjimenezgonzalez9292
    @felixjimenezgonzalez9292 2 роки тому +1

    Great video! Managed to do it thanks to you :D Thanks a lot for the content once more!

  • @mrengithm
    @mrengithm 8 місяців тому

    Great content. May I know extension to create component and guards?

  • @raygabrielvelasquez5492
    @raygabrielvelasquez5492 2 роки тому +1

    THANKYOU MY FRIEND!

  • @curtismaple
    @curtismaple Рік тому

    Greet video! Thnx!
    What theme you use in VSCode?

  • @alexandroskourtis5268
    @alexandroskourtis5268 2 роки тому +2

    φιλε εισαι απλα θεος

    • @CodeShotsWithProfanis
      @CodeShotsWithProfanis  2 роки тому

      Πολύ χαίρομαι που σου άρεσε φίλε μου!! :)

  • @maheshkala8641
    @maheshkala8641 2 роки тому +2

    Great video, really helped me to understand the concept.

  • @ElmarAmanov
    @ElmarAmanov 2 роки тому +1

    great video for us we wait others thanks

  • @matheusjordan6031
    @matheusjordan6031 5 місяців тому +1

    very helpfull

  • @ferooref7614
    @ferooref7614 3 роки тому +3

    Useful video, thanks

  • @abdelmuniemmohamed2638
    @abdelmuniemmohamed2638 2 роки тому +1

    Thanks, very helpful.

  • @rconr007
    @rconr007 3 роки тому +1

    What plug in are you using in viscose for schematics?

    • @CodeShotsWithProfanis
      @CodeShotsWithProfanis  3 роки тому +1

      I use the Angular Schematics extension which you can find here marketplace.visualstudio.com/items?itemName=cyrilletuzi.angular-schematics

  • @fredericoasoares
    @fredericoasoares 2 роки тому +1

    Great video!

  • @mohamedzaki4332
    @mohamedzaki4332 3 роки тому +1

    Very Nice And Useful

  • @alessandrocinque4542
    @alessandrocinque4542 3 роки тому +1

    What is the syntax to allow more than one role to access the page?

    • @CodeShotsWithProfanis
      @CodeShotsWithProfanis  3 роки тому +1

      You can provide an array of roles in the routing configuration (ua-cam.com/video/YJ4dgoHEmGs/v-deo.html) and then you have to check if the values of the given array exist in the array with the roles you get from the token.
      The code below will accomplish this.
      const arr = ['foo', 'bar']
      const arr1 = ['foo', 'baz']
      const isBoolean = arr.some(it => arr1.includes(it))

    • @alessandrocinque4542
      @alessandrocinque4542 3 роки тому

      @@CodeShotsWithProfanis many thanks!

  • @TheKkranthi
    @TheKkranthi 3 роки тому +1

    Great video. Really helpful

  • @murinho7
    @murinho7 3 роки тому +1

    can you do a video where the admin sees a different navigation bar then the user?

  • @gibranaakib7386
    @gibranaakib7386 3 роки тому +1

    Hi
    After that how to hide components based on role provided in route of data

    • @CodeShotsWithProfanis
      @CodeShotsWithProfanis  3 роки тому

      Hi Gibran. I plan to finish a series of videos with "Libraries How-To' and this will be the next video.

    • @gibranaakib7386
      @gibranaakib7386 3 роки тому +1

      @@CodeShotsWithProfanis now i got that but i could be very help to other's
      Thanks for quick reply

  • @MikeyCoree
    @MikeyCoree Рік тому

    Thank you for this awesome tutorial series!
    I'm just in my first month of learning Angular so I cannot guarantee I got everything perfectly correct, but I'll leave here the issues I've encountered and how I solved them, in case it will help anyone (I used Angular 16) :
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    * has-role.guard.ts *
    - From what I understand 'implements CanActivate' in Angular Guards is deprecated in Angular 16; I found out because I do not have a VSC plugin to generate angular elements by right clicking on folders, I use the CLI instead and this is the command :
    ng generate guard hasRole
    - I replaced the assignation of isAuthorized variable from 'this.authService.user.roles.includes(route.data.role);' to
    'return authService.userRole?.role.includes(route.data['role']) ?? false;'
    Because I got the error 'type '(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => boolean | undefined' is not assignable to type 'CanActivateFn'.
    Type 'boolean | undefined' is not assignable to type 'boolean | UrlTree | Observable | Promise'.
    Type 'undefined' is not assignable to type 'boolean | UrlTree | Observable | Promise'.'
    The error is related to the return type mismatch in hasRoleGuard function. The CanActivateFn type expects the guard function to return a boolean, a UrlTree object, an Observable, or a Promise. However, guard function was returning boolean | undefined.
    To resolve the issue, you can update your guard function to explicitly return a boolean value.
    In the updated code:
    The return type of the guard function is explicitly set as boolean.
    The AuthService is injected using the inject function from @angular/core, and its type is casted to AuthService.
    The ?. optional chaining operator is used to safely access the role property of authService.userRole.
    The nullish coalescing operator ?? is used to provide a default value of false if the result of authService.userRole?.role.includes(route.data['role']) is null or undefined.
    - Here's how my has-role.guard.ts code looked in the end: -
    import { CanActivateFn, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
    import { AuthService } from '../services/auth.service';
    import { Injectable, inject } from '@angular/core';
    export const hasRoleGuard: CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean => {
    const authService = inject(AuthService) as AuthService;
    const router = inject(Router);
    // console.log("user role: "+authService.userRole?.role);
    const isAuthorized = authService.userRole?.role.includes(route.data['role']) ?? false;
    if(!isAuthorized){
    router.navigate(['']);
    }
    return isAuthorized;
    };
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    * auth.service.ts *
    - In the constructor I replaced the assignation of this.userRole variable from 'this.userRole = this.getUserRole(this.token); to
    ' this.userRole = this.token ? this.getUserRole(this.token) : null; '
    Because I got the error 'Type 'null' is not assignable to type 'string'.'
    The ternary operator this.token ? this.getUserRole(this.token) : null is used to conditionally assign the value of this.getUserRole(this.token) to this.userRole if this.token is not null. If this.token is null, this.userRole is assigned the value undefined.
    This way, you avoid the error when this.token is null, and this.userRole will be assigned the appropriate value based on the token's availability.
    - I replaced the method in tap function from login method too:
    this.userRole = response.token ? this.getUserRole(response.token) : undefined;
    - I used 'user?: User' instead of 'user!: User' because I got the error
    'Type 'User | undefined' is not assignable to type 'User'. Type 'undefined' is not assignable to type 'User'. ' triggered on the 2 this.user assigns mentioned above
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    * user.Role / user.role / user.roles / user.Roles *
    - Make sure you use just one of them, in all the places, including JWT property, User model, your auth.service, has-role.guard