Issue
The code snippet below is an Angular service to authenticate a user using Laravel Sanctum:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private baseURL = "http://localhost:8000/api";
constructor(private http: HttpClient,public router: Router) { }
login(username: string, password: string): Observable<boolean> {
return this.http.post<{token: string}>(this.baseURL+'/login', {email: username, password: password})
.pipe(
map(result => {
localStorage.setItem('access_token', result.token);
return true;
})
);
}
getToken() {
return localStorage.getItem('access_token');
}
logout() {
let removeToken = localStorage.removeItem('access_token');
if (removeToken == null) {
this.router.navigate(['login']);
}
}
public get isLoggedIn(): boolean {
//TODO: Check token expiry and other security checks
return (localStorage.getItem('access_token') !== null);
}
}
My question is, if am using spatie permissions or Laravel Gates for authorization how can I store them on the frontend so that I can be able to show or hide menus based on what user is allowed to access?
DISCLAIMER: I'm used to developing applications using blade templates. First time I'm switching to SPA.
Solution
After authentication (successful login) you can manage your authorization (access right) via:
If the component is accociated with a route, your need to protect the routes. In this case use:
- Route Guards to protect accessing components under particular URL tree from unauthrized users.
If the component is embedded in the view (like a button or section of a view under open or protected route) then you can:
- Use property binding with
[hidden]="condition"
html property if you want to just hide an element from the UI but not from the DOM. - Use built-in Angular directive *ngIf="condition" if you want to hide or show an element in the UI
and
the DOM based on certain condition.
Say you want to grant access to item A
in menu only to Super_Admin
users.
You can do this:
<ng-container *ngIf="rolePropertyFromAPI === 'Super_Admin'">Item A</ng-container>
This is a big topic where you can find so much on-line. Check medium and Angular In-depth blog posts to know how to implement such strategies. First step is of course the DOCS here
For storing access credits like the 'Super_Admin' above it is a pretty straightforward. You have three options here:
- localStorage or
- sessionStorage or
- cookies.
The optimal one from easy of access and durability is localStorage API. However it is not that safe. It does the job for you though.
The most advanced and tricky one is to store the credentials in the application state using Observables for example.
With localStorage:
1- you accesss your API endpoint response
2- set the property in the browser storage
localStorage.setItem('Super_Admin', JSON.stringify(valueFromBackendEnd))
3- get the value by the key stored with
localStorage.getItem('Super_Admin')
4- clear the storage.
localStorage.removeItem('Super_Admin')
Answered By - onrails
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.