Реализация статуса Read Only

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Drugpunker
Сообщения: 187
Зарегистрирован: 2014.08.13, 19:44

Реализация статуса Read Only

Сообщение Drugpunker »

Здравствуйте всем.
Хочу попросить совета по сабжу.
Нужно добавить функционал для работы с "забаненными" юзерами.

Сделал табличку. Пусть будет erring_souls.
В табличку эту, будут добавляться данные (user_id, blocked_till, и.т.п...).
Добавляться будут админом.
Проверка "а забанен ли я" будет осуществляться при логине пользователя.
Тут попутный вопрос.
Как разлогинить пользователя, если отправил его в бан?
Разблокирование - также при логине.

К тому же, в таблице юзера есть поле status.
Нужно оно для проверки активен он или нет. Допустим, когда зарегился, но не подтвердил email - Неактивен.

По-сему, придётся контролировать 2 таблицы.
users.status и erring_souls.
Не может же быть активным забаненный пользователь.
Вроде всё логично, но как-то не изящно. :)

Через rbac реализовать наверно не получится, потому что роли у меня зарезервированы, например (admin, moder, user, god).
А добавлять роль BLOCKED/ACTIVE к имеющимся, есть неправильно.

Прошу совета, как кто прорабатывает сию концепцию?
Да и вообще, правильно ли я рассуждал, организуя такой подход?
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Реализация статуса Read Only

Сообщение unknownby »

Реализовывал такое в плане "Отключить" пользователя. Обычный чекбокс в записи пользователя и проверка при логине на актуальность учетки, а проверку "в бане" или нет, можно сделать в конфиге, как вариант, в beforeAction и если "в бане", то разлогинить его перенаправив на страницу logout, при повторном логине будет писать, что забанен и не даст войти. :)
Отключена или нет, В бане или нет - можно обычными чекбоксами.
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: Реализация статуса Read Only

Сообщение skynin »

-- Как разлогинить пользователя, если отправил его в бан?
обычно просто удалить его сессию.

-- Разблокирование - также при логине.
непонятный момент.
Кто блокировал? Админ. Ну он пусть и разблокирует.

-- Прошу совета, как кто прорабатывает сию концепцию?
да почти все, у кого есть пользователи на сайте

и для валидации почты все готово. в штатной таблице типовых шаблонов Yii даже поле есть для токена.
Один только нюанс
ответить пользователю при логине что он забанен :)

а так, типовой функционал сайта где пользователи могут регистрироваться и логиниться для совершения каких-то действий, недоступных гостям.
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
Drugpunker
Сообщения: 187
Зарегистрирован: 2014.08.13, 19:44

Re: Реализация статуса Read Only

Сообщение Drugpunker »

unknownby писал(а): 2020.09.07, 15:57 Реализовывал такое в плане "Отключить" пользователя. Обычный чекбокс в записи пользователя и проверка при логине на актуальность учетки, а проверку "в бане" или нет, можно сделать в конфиге, как вариант, в beforeAction и если "в бане", то разлогинить его перенаправив на страницу logout, при повторном логине будет писать, что забанен и не даст войти. :)
Отключена или нет, В бане или нет - можно обычными чекбоксами.
Я так и планирую сделать. Только не чек, а дропдаун.
Но бан может быть дан на день/неделю/нувобщепрямнавсегда.
Хотя, это наверно неважно.
В целом, верное направление избрал?
Drugpunker
Сообщения: 187
Зарегистрирован: 2014.08.13, 19:44

Re: Реализация статуса Read Only

Сообщение Drugpunker »

skynin писал(а): 2020.09.07, 16:18 -- Разблокирование - также при логине.
непонятный момент.
Кто блокировал? Админ. Ну он пусть и разблокирует.
Если логинится забаненный, проверяется дата в поле blocked_till.
Если дата наступила - деактивировать статус этой строки в таблице для хранения банов.
Админ здесь не нужен.
skynin писал(а): 2020.09.07, 16:18 Один только нюанс
ответить пользователю при логине что он забанен :)
$model->addError("You are banned till..."). :)
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: Реализация статуса Read Only

Сообщение skynin »

-- Если дата наступила - деактивировать статус этой строки в таблице для хранения банов.
если такая бизнес логика, то так и делать.

-- $model->addError("You are banned till...")
вообще-то первым параметром указывается атрибут. Обычно.

ну а в типичном LoginForm так и сделано.
а дальше, в views\site\login.php ActiveForm выведет к соответствующему полю сообщение это сообщение.
Или, там, проверять тип ошибки, и генерить другой html - Вы забанены до даты

Если, конечно, не реализовано api.

а в чем вопрос тогда?

в "В целом, верное направление избрал?"
так так реализовано в шаблонах
вам только правило добавить для обработки дата в поле blocked_till.

-- Вроде всё логично, но как-то не изящно.
вот это непонятно зачем:
Сделал табличку. Пусть будет erring_souls.
В табличку эту, будут добавляться данные (user_id, blocked_till, и.т.п...).

зачем другая табличка, почему нельзя хранить в той же - user?
хотя тоже непонятно зачем, почему не атрибутами таблицы

-- придётся контролировать 2 таблицы.
-- users.status и erring_souls.
да, непонятно зачем нужна erring_souls, а не атрибут blocked_till

если их много всяких, то можно и в json поле засунуть.

-- потому что роли у меня зарезервированы, например (admin, moder, user, god).
Yii предоставляет два метода авторизации: фильтры контроля доступа (ACF) и контроль доступа на основе ролей (RBAC).
https://www.yiiframework.com/doc/guide/ ... horization
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Реализация статуса Read Only

Сообщение unknownby »

Drugpunker писал(а): 2020.09.07, 16:27 Я так и планирую сделать. Только не чек, а дропдаун.
Но бан может быть дан на день/неделю/нувобщепрямнавсегда.
Хотя, это наверно неважно.
В целом, верное направление избрал?
Ну вообще самый простой способ реализации бана, как в ВК. Там выбираешь на сколько человека забанить в группе и в дропдауне, он сразу показывает дату окончания бана отсчитывая от текущего момента времени.
Насчет удаления сессии такое себе конечно, но как вариант имеет место быть, просто мало ли заблокировать нужно в определенном месте, а в других местах должен иметь доступ, тогда тут реализация должна быть чуть хитрее, чем просто удаление сессии.
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: Реализация статуса Read Only

Сообщение skynin »

-- а в других местах должен иметь доступ
тогда надо реализовывать проверку набора прав.
самый простой из штатных - ACF. если нужно на уровне action контроллера

можно и проще, тупо ifaми проверять, в тех редких местах где есть какие-то ограничения
но тогда и бан превращается не в бан, а в некую роль выданную на время.
но все это можно упрятать в свой, не RBACовский, \Yii::$app->user->can где проверяется и бан, и admin, moder, user, god

Если и на уровень запросов надо пробросить, то виртуальное поле можно добавить. и не одно, а сколько нужно, которое будет работать на основе бана, и admin, moder, user, god

А как надо?
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
Drugpunker
Сообщения: 187
Зарегистрирован: 2014.08.13, 19:44

Re: Реализация статуса Read Only

Сообщение Drugpunker »

-- а в чем вопрос тогда?
Поговорить, услышать мнения. Мало ли, вдруг кто-то нашёл интересный и лаконичный подход.
К примеру, подход убирающий поле status из
таблицы пользователей, и совмещающий в себе работу только лишь с таблицей заблокированных. Я такого не придумал.

-- вам только правило добавить для обработки дата в поле blocked_till.
Сначала так и сделал. Но уже сейчас пришёл к выводу, что юзеру и админу тоже (для истории и статистики) было бы неплохо знать причину блокировки. Поэтому тут только отдельная таблица.

-- да, непонятно зачем нужна erring_souls, а не атрибут blocked_till
Выше ответил.

-- фильтры контроля доступа (ACF) и контроль доступа на основе ролей (RBAC).
https://www.yiiframework.com/doc/guide/ ... horization
Нууу, от acf здесь вроде как толка ноль, т.к. придётся во всех контроллерах (во многих) кучу правил прописывать.
А вот rbac... не представляю как сделать, оять же красиво.
В гайде говорится о вложенных ролях. Но блин как это сделать, если у меня уже имеются роли admin, moder, user, god?
Добавлять группы ролей?
Например statusRole(для бан/не бан) и permissionRole (для субролей admin, moder, user, god). Как-то мегакостыльно выглядит, даже в теории.
Drugpunker
Сообщения: 187
Зарегистрирован: 2014.08.13, 19:44

Re: Реализация статуса Read Only

Сообщение Drugpunker »

unknownby писал(а): 2020.09.07, 17:15
Drugpunker писал(а): 2020.09.07, 16:27 Я так и планирую сделать. Только не чек, а дропдаун.
Но бан может быть дан на день/неделю/нувобщепрямнавсегда.
Хотя, это наверно неважно.
В целом, верное направление избрал?
Ну вообще самый простой способ реализации бана, как в ВК. Там выбираешь на сколько человека забанить в группе и в дропдауне, он сразу показывает дату окончания бана отсчитывая от текущего момента времени.
Насчет удаления сессии такое себе конечно, но как вариант имеет место быть, просто мало ли заблокировать нужно в определенном месте, а в других местах должен иметь доступ, тогда тут реализация должна быть чуть хитрее, чем просто удаление сессии.
Хотел сначала локальные ограничения сделать. Но посчитал, если уж ридонли, то и логиниться смысла нет, ибо все пермишшны на авторизованных завязаны. Накосячил - читай и всё. А та та.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Реализация статуса Read Only

Сообщение unknownby »

Drugpunker писал(а): 2020.09.07, 21:20 Хотел сначала локальные ограничения сделать. Но посчитал, если уж ридонли, то и логиниться смысла нет, ибо все пермишшны на авторизованных завязаны. Накосячил - читай и всё. А та та.
Если авторизированный может делать еще что-то, а неавторизированный только читать, то делаем блокировку внутри записи пользователя (плюс прописываем для истории в отдельную таблицу users_id, причину блокировки и даты блокировки). При проставлении бана, чтоб разлогинить человека можно как вариант сделать так

Код: Выделить всё

'on beforeAction' => function ($event) {
        if(!empty(\Yii::$app->user->identity)){
        //проверка на бан
        //если в бане, то Url::toRoute('/user/auth/logout')
        }
    },
Т.е. не важно где пользователь будет находиться, если он залогинен и он оказался в бане, то выкинет сразу. Без удалений сессии.
При логине проверять на активированность учетной записи (да/нет) и выдавать соответствующую информацию пользователю, ну и в бане (да/нет), также выдавать информацию пользователю.

Можно конечно и по другому как-то, наверное :D Подскажут другие люди, которые такое делали в своей системе.
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: Реализация статуса Read Only

Сообщение skynin »

-- Мало ли, вдруг кто-то нашёл интересный и лаконичный подход
а что его искать, он стопицот раз реализован :)
поэтому и непонятно, а в чем вопрос об изобретении колеса :)

-- К примеру, подход убирающий поле status из таблицы пользователей
Это не подход. А - надо - убирайте. Не надо - не убирайте.

-- Но уже сейчас пришёл к выводу, что юзеру и админу тоже (для истории и статистики) было бы неплохо знать причину блокировки
Описание причины можно задать в самой записи user.
Зачем отдельная таблица?
На кой, с какой целью потом ее джойнить или искать по ней?

-- Нууу, от acf здесь вроде как толка ноль, т.к. придётся во всех контроллерах (во многих) кучу правил прописывать.
Ну значит не прописывайте.
Ваша же система прав - вам и карты в руки.
Если она как бы есть, но можно все - то да, зачем acf, одного if`а может хватить.

-- А вот rbac... не представляю как сделать, оять же красиво.
Вторая таблица выглядит уродливо. Потому что - непонятно зачем она.

Но, споры о красоте - это бессмысленно конечно.

-- Добавлять группы ролей?
Если надо - добавляйте.
Если не надо - не добавляйте.

Зависит от тех задания, в виде таблички
Роль Комментарии ... ...
god Чтение+/Изменение+
read-only Чтение+/Изменение-
и т.д.

Если у вас нет такой таблички для вашей системы - то и рационально обоснованные критерии выбора решения невозможны.
"Без ТЗ и результат ХЗ"

Красота... это пустое, вкусовщина. Причем у начинающего одни понятия о красоте, а у опытного нередко противоположные ;)
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
Drugpunker
Сообщения: 187
Зарегистрирован: 2014.08.13, 19:44

Re: Реализация статуса Read Only

Сообщение Drugpunker »

unknownby писал(а): 2020.09.08, 08:43
Drugpunker писал(а): 2020.09.07, 21:20 Хотел сначала локальные ограничения сделать. Но посчитал, если уж ридонли, то и логиниться смысла нет, ибо все пермишшны на авторизованных завязаны. Накосячил - читай и всё. А та та.
Если авторизированный может делать еще что-то, а неавторизированный только читать, то делаем блокировку внутри записи пользователя (плюс прописываем для истории в отдельную таблицу users_id, причину блокировки и даты блокировки). При проставлении бана, чтоб разлогинить человека можно как вариант сделать так

Код: Выделить всё

'on beforeAction' => function ($event) {
        if(!empty(\Yii::$app->user->identity)){
        //проверка на бан
        //если в бане, то Url::toRoute('/user/auth/logout')
        }
    },
Т.е. не важно где пользователь будет находиться, если он залогинен и он оказался в бане, то выкинет сразу. Без удалений сессии.
При логине проверять на активированность учетной записи (да/нет) и выдавать соответствующую информацию пользователю, ну и в бане (да/нет), также выдавать информацию пользователю.

Можно конечно и по другому как-то, наверное :D Подскажут другие люди, которые такое делали в своей системе.
Ага, почти также и мыслю.
Спасибо.
Кстати, могу попутно уточнить давно интересующий вопрос?
У меня во всём проекте получение id, да и все манипуляции с бд производятся через отлов Yii::$app->user->id, если требуется id юзера.
Любые проверки, присваивания и т.п.
Бывает встречаю Yii::$app->user->identity.
В чём разница?
Не читал, не вникал. Просто, спрашиваю, раз уж диалог ведётся. Конечно разберусь в этом, когда время найдётся, но не сейчас. :)
Это нормально? То есть правильно/безопасно?
Drugpunker
Сообщения: 187
Зарегистрирован: 2014.08.13, 19:44

Re: Реализация статуса Read Only

Сообщение Drugpunker »

skynin писал(а): 2020.09.08, 10:04 -- Но уже сейчас пришёл к выводу, что юзеру и админу тоже (для истории и статистики) было бы неплохо знать причину блокировки
Описание причины можно задать в самой записи user.
Зачем отдельная таблица?
На кой, с какой целью потом ее джойнить или искать по ней?

-- А вот rbac... не представляю как сделать, оять же красиво.
Вторая таблица выглядит уродливо. Потому что - непонятно зачем она.
Появляется к примеру грубый, хамоватый, надменный выскочка-юзер, который часто позволяет себе неправомерные действия.
Обматерил кого, ок в бан на неделю.
Обматерил опять.
Админ смотрит историю по данному (любому) выскочке, перед принятием решения. Видит, ага, рецидивист :).
Ну давай теперь на месяц. :)
Такой замысел.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Реализация статуса Read Only

Сообщение unknownby »

Drugpunker писал(а): 2020.09.08, 21:48 Ага, почти также и мыслю.
Спасибо.
Кстати, могу попутно уточнить давно интересующий вопрос?
У меня во всём проекте получение id, да и все манипуляции с бд производятся через отлов Yii::$app->user->id, если требуется id юзера.
Любые проверки, присваивания и т.п.
Бывает встречаю Yii::$app->user->identity.
В чём разница?
Не читал, не вникал. Просто, спрашиваю, раз уж диалог ведётся. Конечно разберусь в этом, когда время найдётся, но не сейчас. :)
Это нормально? То есть правильно/безопасно?
На сколько я понял, то Yii::$app->user->id это просто взять идентификатор пользователя, а Yii::$app->user->identity посложнее, сохранение параметров в сессии и их использование после авторизации пользователя.мат.часть
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Реализация статуса Read Only

Сообщение ElisDN »

Drugpunker писал(а): 2020.09.08, 21:48 В чём разница?
Ни в чём. Геттер для user->id внутри дёргает user->identity->id.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Реализация статуса Read Only

Сообщение unknownby »

ElisDN писал(а): 2020.09.09, 09:14
Drugpunker писал(а): 2020.09.08, 21:48 В чём разница?
Ни в чём. Геттер для user->id внутри дёргает user->identity->id.
Между этими ни в чем, а если смотреть на user->identity?
Drugpunker
Сообщения: 187
Зарегистрирован: 2014.08.13, 19:44

Re: Реализация статуса Read Only

Сообщение Drugpunker »

unknownby писал(а): 2020.09.09, 08:49
Drugpunker писал(а): 2020.09.08, 21:48 Ага, почти также и мыслю.
Спасибо.
Кстати, могу попутно уточнить давно интересующий вопрос?
У меня во всём проекте получение id, да и все манипуляции с бд производятся через отлов Yii::$app->user->id, если требуется id юзера.
Любые проверки, присваивания и т.п.
Бывает встречаю Yii::$app->user->identity.
В чём разница?
Не читал, не вникал. Просто, спрашиваю, раз уж диалог ведётся. Конечно разберусь в этом, когда время найдётся, но не сейчас. :)
Это нормально? То есть правильно/безопасно?
На сколько я понял, то Yii::$app->user->id это просто взять идентификатор пользователя, а Yii::$app->user->identity посложнее, сохранение параметров в сессии и их использование после авторизации пользователя.мат.часть
Спасибо большое.
Гляну. Прочту.
Drugpunker
Сообщения: 187
Зарегистрирован: 2014.08.13, 19:44

Re: Реализация статуса Read Only

Сообщение Drugpunker »

ElisDN писал(а): 2020.09.09, 09:14
Drugpunker писал(а): 2020.09.08, 21:48 В чём разница?
Ни в чём. Геттер для user->id внутри дёргает user->identity->id.
Понял.
Спасибо.
Drugpunker
Сообщения: 187
Зарегистрирован: 2014.08.13, 19:44

Re: Реализация статуса Read Only

Сообщение Drugpunker »

unknownby писал(а): 2020.09.08, 08:43 Если авторизированный может делать еще что-то, а неавторизированный только читать, то делаем блокировку внутри записи пользователя (плюс прописываем для истории в отдельную таблицу users_id, причину блокировки и даты блокировки). При проставлении бана, чтоб разлогинить человека можно как вариант сделать так

Код: Выделить всё

'on beforeAction' => function ($event) {
        if(!empty(\Yii::$app->user->identity)){
        //проверка на бан
        //если в бане, то Url::toRoute('/user/auth/logout')
        }
    },
Т.е. не важно где пользователь будет находиться, если он залогинен и он оказался в бане, то выкинет сразу. Без удалений сессии.
При логине проверять на активированность учетной записи (да/нет) и выдавать соответствующую информацию пользователю, ну и в бане (да/нет), также выдавать информацию пользователю.

Можно конечно и по другому как-то, наверное :D Подскажут другие люди, которые такое делали в своей системе.
Блин, можешь пояснить.
Чёт не могу я понять как сопоставить identity и конкретного юзера.
Это ж через куки, только для текущего.
То есть админ будет логаутить себя. :)
Ответить