How I expose Laravel permissions in Vue.js

Imagine you want in Vue.js to do something like:

<h1 v-if="Laravel.user.can['manage users']">You have permission to manage users</h1>
<h1 v-else>You dont have permission to manage users</h1>

So you want to use Laravel permissions (server side) in Vue.js (frontend/client side)… Here is a little guide of how I expose Laravel permissions (https://laravel.com/docs/5.4/authorization) to vue.js using amazing Laravel permission package ( https://github.com/spatie/laravel-permission).

Configuration on backend

Install laravel-permission package. See:

https://github.com/spatie/laravel-permission#installation.

Add Laravel user object to Javascript with the following Javascript snippet in your html header, multiple ways of doing this:

Before Laravel 5.4.23 a window.Laravel global javascript object exists, you could add user to this object using:

<script>
window.Laravel = {!! json_encode([
'csrfToken' => csrf_token(),
'user' => Auth::user()
]) !!};
</script>

Or Like in 5.4.23 and before you can use meta tags:

<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="user" content="Auth::user()">

and in bootstrap.js or similar file done something like:

let user = document.head.querySelector('meta[name="user"]');

If you use Laravel default Laravel scaffolding (see command make:auth https://laravel.com/docs/5.4/authentication#introduction) you have to only done litle changes tho the existing files.

You can also publish only permissions and/or roles if you don’t want to expose all user object to javascript with something like:

<script>
window.Laravel = {!! json_encode([
'csrfToken' => csrf_token(),
'roles' => Auth::user()->roles
]) !!};
</script

Laravep permission package don’t expose by default roles and permissions in Json serialization of user object so you have to apply the following changes to App\User class (apply a Trait):

Trait ExposePermissions
....


/**
* Get all user permissions.
*
* @return bool
*/
public function getAllPermissionsAttribute()
{
return $this->getAllPermissions();
}

/**
* Get all user permissions in a flat array.
*
* @return array
*/
public function getCanAttribute()
{
$permissions = [];
foreach (Permission::all() as $permission) {
if (Auth::user()->can($permission->name)) {
$permissions[$permission->name] = true;
} else {
$permissions[$permission->name] = false;
}
}
return $permissions;
}

At the trait to you User Model and appends the attributes to json:

/**
* The accessors to append to the model's array form.
*
* @var array
*/
protected $appends = ['all_permissions','can']

Front-end

We want to use Laravel permission package roles and permissions in Javascript with Conditional rendering (https://vuejs.org/v2/guide/conditional.html) using the following:

<h1 v-if="Laravel.user.can['manage users']">You have permission to manage users</h1>
<h1 v-else>You dont have permission to manage users</h1>

Or if you have been published a user javascript global object:

<h1 v-if="user.can['manage users']">You have permission to manage users</h1>
<h1 v-else>You dont have permission to manage users</h1>

Security note

Never depends only in Javascript for security because Javascript code could be tampered by final users. So only use this technique when you also use backend security.

Some notes and code can be found here:

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.