Display Name
Display Name

Reputation: 130

Looking to Add Role-Based Authentication System

I was wondering if anyone would be able to help with this here:

I'm looking to create a role-based authorization service and I'm not sure how to get the reference in the service.

Here is some of the code: header.component.html

<button mat-button routerLink="/staff" *ngIf="authService.canStaff == true">Staff</button>

header.component.ts

import { AuthService } from '../services/auth.service';
...
constructor(
    public authService: AuthService
  ) { }

auth.service.ts

public userData: any; // Save logged in user data

  constructor(
    public afs: AngularFirestore,   // Inject Firestore service
    public afAuth: AngularFireAuth, // Inject Firebase auth service
    public router: Router,  
    public ngZone: NgZone // NgZone service to remove outside scope warning
  ) {    
    /* Saving user data in localstorage when 
    logged in and setting up null when logged out */
    this.afAuth.authState.subscribe(user => {
      if (user) {
        //this.userData = this.afs.doc('users/${user.uid}');
        this.userData = user;
        localStorage.setItem('user', JSON.stringify(this.userData));
        JSON.parse(localStorage.getItem('user'));
      } else {
        localStorage.setItem('user', null);
        JSON.parse(localStorage.getItem('user'));
      }
    })

  }

...

canStaff(user: User): boolean {
    const allowed = ['admin', 'staff']
    return this.checkAuthorization(user, allowed)
  }

public checkAuthorization(user: User, allowedRoles: string[]): boolean {
    if (!user) return false
    for (const role of allowedRoles) {
      if (user.roles[role]) {
        return true
      }
    }
    return false
  }

I'm looking for it to show the button when the user with the staff and admin role sees it, and hide it when the user does not have either of those roles.

The current result is the button is constantly hidden. Hopefully this is the right place to ask.

Upvotes: 0

Views: 177

Answers (1)

toothful
toothful

Reputation: 892

JSON.parse(localStorage.getItem('user')); you did not set this to any variable. What is the point? Also canStaff expects User argument to be passed.

How about -

canStaff(user: User): boolean {
    const allowed = ['admin', 'staff']
    return this.checkAuthorization(JSON.parse(localStorage.getItem('user')), allowed)
  }

And most importantly below section should be moved to login component. After successful login, get user data, set to localstorage and only after that you should redirect to your next landing page. make sure you clean up your localstorage after logout.

this.afAuth.authState.subscribe(user => {
  if (user) {
    //this.userData = this.afs.doc('users/${user.uid}');
    this.userData = user;
    localStorage.setItem('user', JSON.stringify(this.userData));
  } else {
    localStorage.setItem('user', null);
  }
})

And

<button mat-button routerLink="/staff" *ngIf="authService.canStaff() == true">Staff</button>

Upvotes: 1

Related Questions