Как обрабатывать роли / разрешения в SPA (Laravel + Vue)

Я слышал много шума о СПА, поэтому подумал, давайте попробуем, и начал работать над СПА-проектом с Laravel + Vue.

Я начал с создания CRUD с помощью axios и vue-router. Все шло отлично, пока мне не потребовалось авторизовать пользователей и принимать решения на основе их ролей. Я понял, что теперь, когда у меня нет преимущества рендеринга на стороне сервера (директивы лезвия), мне придется работать на стороне vue, чтобы управлять ролями / разрешениями и т. Д. Но я не знаю, как я могу подойти к этому. .. Каковы лучшие практики ... Есть ли какие-то подводные камни, о которых следует знать ... и т. Д. И т. Д.

Итак, я начал свое исследование и то, что я собрал из здесь, там и здесь, что я пришлось бы хранить данные в объекте JS или localStorage, чтобы выполнить что-то вроде этого:

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

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

Но что, если пользователь, который на самом деле не администратор, а модератор, выполнит это Laravel.user.role.push('admin') в консоли? Разве эти конфиденциальные данные не будут переданы ему?

Также localStorage доступен следующим образом: localStorage.getItem('user.role')

Итак, что является / являются безопасным / стандартным / наиболее распространенным способом (-ами) решения подобных ситуаций?


person Tanmay    schedule 26.07.2018    source источник
comment
Проверяйте разрешения на стороне сервера, возвращайте только авторизованные данные.   -  person emix    schedule 26.07.2018
comment
@emix Скажем, у меня есть 3 вкладки: Главная, Профиль, Действие, и я хочу, чтобы вкладка действия была видна только авторизованному пользователю, как эта вкладка может быть проверена на стороне сервера, если я уже отрендерил все вкладки?   -  person Tanmay    schedule 26.07.2018
comment
Проблема @Eisenheim заключается в том, что <p v-if="Laravel.user.role == 'admin'"> Confidential Data </p> будет скомпилирован в javascript, поэтому каждый пользователь может увидеть его, если приложит к нему усилия, вам нужно сделать вызов api в компоненте, который извлекает `` конфиденциальные данные '' из конечной точки api только администратор может получить доступ   -  person Quezler    schedule 26.07.2018
comment
Хорошо, я понял вашу точку зрения. Но отправка только авторизованных данных станет настоящим кошмаром. Можете ли вы помочь мне с помощью моей ранее упомянутой аналогии с вкладками? Если бы вас попросили скрыть элемент вкладки или элемент меню, как бы вы его скрыли?   -  person Tanmay    schedule 27.07.2018
comment
@Tanmay, что в итоге сработало для вас лучше всего?   -  person Thomas    schedule 18.02.2020
comment
Ничего такого. Я просто не отображаю конфиденциальные данные, как ранее предлагал emix. Кроме того, я рассчитываю на страшные, загадочные, объединенные и минифицированные js-блоки.   -  person Tanmay    schedule 18.02.2020


Ответы (2)


Я думаю, что лучший способ - хранить данные внутри Vuex, если вы используете магазин, или вы можете использовать прототип и использовать Vue.prototype. $ UserPerms = axios.get (), и вы сможете использовать this. $ UserPerms в каждом компоненте.

Но лучший способ защитить данные - это то, что API не может возвращать данные, которые не могут быть просмотрены пользователем. Так что если какие-то его роли как-то взломают. Он по-прежнему не может видеть данные, потому что они не возвращаются API.

person Mako    schedule 26.07.2018

Управляйте доступом к данным в Laravel, а затем используйте @casl во внешнем интерфейсе, чтобы выполнить дополнительную логику на основе разрешений.

npm install @casl/vue @casl/ability

Пакеты:

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

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

Пример приложения:

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

Руководство:

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

person nathanjessen    schedule 18.07.2019