How to handle roles/permissions in an SPA (Laravel+Vue)
Asked Answered
A

2

10

I have been hearing a lot of buzz about SPAs, so I thought let's give it a shot and I started working on an SPA project with Laravel+Vue.

I started with making some CRUDs with the help of axios and vue-router. Everything worked out great, until I needed to authorize users and make decisions based on their roles. I realized that now that I don't have the advantage of server-side rendering (blade directives) I would have to work on the vue side to manage the roles/permissions etc. But I don't know how I can approach that... What are the best practices... Are there any gotchas to be aware of... etc. etc.

So I started my research and what I gathered from here, there, and there is that I would have to store the data in a JS object or localStorage in order to perform something like this:

<p v-if="Laravel.user.role == 'admin'"> Confidential Data </p>

<p v-else> Unimportant Information </p>

But what if the user who is actually not an admin, but a moderator, executes this Laravel.user.role.push('admin') in the console? Wouldn't that sensitive data be exposed to him?

Also the localStorage is available with this: localStorage.getItem('user.role')

So what is/are the secure/standard/most common way(s) of handling situations like this?

Amortizement answered 26/7, 2018 at 9:8 Comment(6)
Validate permissions on the server side, only return authorized data.Jilljillana
@emix Say I have 3 tabs: Home, Profile, Action and I want the action tab to be visible only to the authorized user, how can that one tab be server-side validated, since I have already rendered all the tabs?Amortizement
@Eisenheim problem is that <p v-if="Laravel.user.role == 'admin'"> Confidential Data </p> will be compiled into javascript, thus every user can see it if they put effort into it, what you should to is do an api call in the component that fetches the 'confedential data' from an api endpoint only an admin can accessOmniscient
Okay, I get your point. But sending only the authorized data is going to be one hell of a nightmare. Can you guide me with my previously mentioned "Tab analogy"? If you were asked to hide a Tab Item or Menu Item, how would you hide it?Amortizement
@Amortizement what eventually worked best for you?Guess
Nothing. I am just not rendering the sensitive data as emix had previously suggested. Also, I am counting on webpack's scary, cryptic, bundled and minified js chunks.Amortizement
I
1

I think best way is store data inside Vuex if you use the store or you can use prototype and use Vue.prototype.$userPerms = axios.get() and you will be able to use this.$userPerms in every component.

But best way to protect data is that API cannot return data which are not able to see by user. So if some somehow hack his role. He still not be able to see data because it's not returned by API.

Inoue answered 26/7, 2018 at 9:14 Comment(0)
S
1

Control data access in Laravel then use @casl on the frontend to do some additional permission based logic.

npm install @casl/vue @casl/ability

Packages:

https://www.npmjs.com/package/@casl/vue

https://www.npmjs.com/package/@casl/ability

Example app:

https://github.com/stalniy/casl-vue-api-example

Tutorial:

https://vuejsdevelopers.com/2018/01/08/vue-js-roles-permissions-casl/

Suave answered 18/7, 2019 at 18:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.