Нужно иметь ограничение для пользователя в виде уникального логина. То есть, пока юзер с данным именем залогинен, нельзя под этим именем еще раз войти.
Я в веб-программировании чуть выше нулевого уровня, прошу указать верное направление
Варианта вижу 2:
1. Постоянное соединение с сервером и проверка при логине, нет ли такого.
2. Периодические пинги и проверка при логине, давно ли был пинг с таким именем.
Вариант 1 плох тем, что ОС имеет ограничение на кол-во одновременных соединений (трафик там будет околонулевой, если что). Вроде как в линуксе 1024 по умолчанию. Но можно расширить. Но не безлимит же?
Вариант 2 плох тем, что каждый пинг есть коннект/дисконнект и это тоже нагрузка.
Нужен практический совет с точки зрения перспективности — какой вариант развивать? Или есть вариант 3?
Здравствуйте, CyberDemon, Вы писали:
CD>Нужно иметь ограничение для пользователя в виде уникального логина. То есть, пока юзер с данным именем залогинен, нельзя под этим именем еще раз войти.
Ну это как бы обычное разграничение доступа стандартными средствами. Пользователь с ролью anonim имеет право на вход, а с ролью user — нет.
P.S. Роль anonim может реально и не существовать в коде, но учитывать ее при проектировании доступа, бывает полезно.
Здравствуйте, Qulac, Вы писали:
Q>Ну это как бы обычное разграничение доступа стандартными средствами. Пользователь с ролью anonim имеет право на вход, а с ролью user — нет. Q>P.S. Роль anonim может реально и не существовать в коде, но учитывать ее при проектировании доступа, бывает полезно.
Мне кажется или я плохо объяснил, или вы не так поняли.
У нас есть юзеры user1, user2000, user_lala и прочие. Юзер user2000 поделился паролем с другом. Запустил приложение, залогинился. А потом друг его с другого девайса тоже хочет залогиниться. А вот нельзя — этот юзер уже в системе. Пока первый не разлогинится, больше никто не сможет залогиниться под его именем.
Как я уже сказал, я в этих делах (с точки зрения технической реализации) плаваю
Исходить нужно из наихудшего варианта: пользователь прибил процесс браузера, очистил кеш или еще что-либо. Т.е. нотификации о потери сессии пользователем не произошло. И именно из этого состояния система должна уметь восстанавливаться, например, с помощью умертвления сессий по таймауту.
Остальные механизмы могут лишь помочь системе реагировать быстрее.
Далее: если обмен с сервером регулярный, то возможно специального поллинга и не нужно, но по истечению таймаута сессии он будет вынужден перелогиниваться (в случае бездействия).
Если хочется реагировать прям на закрытие вкладки, есть событие onbeforeunload. Но тогда нужно решить как быть с множеством вкладок пользователя. Т.е. вкладок может быть более одной в рамках одной сессии, в одном браузере.
Кроме того один и тот же пользователь без передачи паролей другим лицам может захотеть воспользоваться сервисом со *своего* аккаунта не только с компьютера, но так же с ноутбука и еще двух смартфонов которые находятся рядом.
Требование в целом понятно, но, если это сервис делается для людей — то лучше смириться с наличием множества сессий с разных устройств. В противном случае, эти всякие гениальные замысловатости, ИМХО, чаще будут отпугивать и вызывать дискомфорт.
Здравствуйте, CyberDemon, Вы писали:
CD>Здравствуйте, Qulac, Вы писали:
Q>>Ну это как бы обычное разграничение доступа стандартными средствами. Пользователь с ролью anonim имеет право на вход, а с ролью user — нет. Q>>P.S. Роль anonim может реально и не существовать в коде, но учитывать ее при проектировании доступа, бывает полезно.
CD>Мне кажется или я плохо объяснил, или вы не так поняли. CD>У нас есть юзеры user1, user2000, user_lala и прочие. Юзер user2000 поделился паролем с другом. Запустил приложение, залогинился. А потом друг его с другого девайса тоже хочет залогиниться. А вот нельзя — этот юзер уже в системе. Пока первый не разлогинится, больше никто не сможет залогиниться под его именем. CD>Как я уже сказал, я в этих делах (с точки зрения технической реализации) плаваю
А что это меняет? Это просто другой аспект разграничения доступа — защита ресурса. Ресурсом тут является учетная запись.
Здравствуйте, CyberDemon, Вы писали:
CD>Нужен практический совет с точки зрения перспективности — какой вариант развивать? Или есть вариант 3?
Еще вариант:
При логине клиент получает уникальный токен. Общаясь с сервером, передает ему этот токен. Сервер запоминает токен последнего обратившегося клиента. Если токен обращения не совпадает, то пользователь отправляется на страницу логина.
Если это реальный пользователь пересел на другой комп, то ему просто придется ввести имя/пароль и он будет спокойно работать на новом компе.
Если это два одновременных пользователя с одним логином, то они будут друг другу мешать — после каждого запроса их будет поочередно перекидывать на страницу входа с требованием ввести пароль.
Сколько одновременных юзеров в системе? Допустим, миллион. Если посылать пинги каждые 15 минут, то будет 1000 rps. С работой справится дешевая vds-ка с nginx-ом и каким-нибудь memcache-м или redis-ом.
Если за предыдущие 15 минут был пинг, повторный логин отклоняется. Если не было — сессия прибивается. Если юзер на 15 минут закроет вкладку или мобильный браузер (мобила отключит все яваскрипты и все пинги для экономии батареи), но юзеру придется перелогиниваться. Если браузер вдруг зависнет и сессионная кука потеряется, юзеру придётся ждать 15 минут пока сервер не прибьёт старую сессию.
Здравствуйте, Буравчик, Вы писали:
Б>При логине клиент получает уникальный токен. Общаясь с сервером, передает ему этот токен. Сервер запоминает токен последнего обратившегося клиента. Если токен обращения не совпадает, то пользователь отправляется на страницу логина.
Б>Если это реальный пользователь пересел на другой комп, то ему просто придется ввести имя/пароль и он будет спокойно работать на новом компе. Б>Если это два одновременных пользователя с одним логином, то они будут друг другу мешать — после каждого запроса их будет поочередно перекидывать на страницу входа с требованием ввести пароль.
Мне ваш вариант нравится. У меня голове что-то похожее было, но "проблема" в том, что на сервер софту не за чем лезть, потому он и отсеивался.
Значит, придумаем причины
Здравствуйте, L.K., Вы писали:
LK>Ну если вот-прям-так-надо...
LK>Сколько одновременных юзеров в системе? Допустим, миллион. Если посылать пинги каждые 15 минут, то будет 1000 rps. С работой справится дешевая vds-ка с nginx-ом и каким-нибудь memcache-м или redis-ом.
Ну а если это приличный VPS с апачем и пхп, насколько производительность падает?
Миллион пользователей — это слишком круто. Это уже успех и там можно будет нанять специальных людей для такой проблемы
Так не делают. Это противоречит принципам веба. Правильный вариант — выбрасывать старого пользователя при логине нового, а ещё более правильный — показывать диалог, что мол залогинен пользователь, последняя активность 30 минут назад, продолжить вход и выкинуть его или отменить вход. Это реализуется тривиально.
При чём тут пхп? Пинги можно обрабатывать самим Nginx-ом (Lua).
Апач — отправить на почётную пенсию.
Специальных людей... ну, может их и наняли. А специальные люди наняли других людей. А те люди наняли студента-фрилансера с уровнем программирования "чуть выше нулевого". И студент интересуется на форуме. Мало ли.
Здравствуйте, CyberDemon, Вы писали:
CD>Нужно иметь ограничение для пользователя в виде уникального логина. То есть, пока юзер с данным именем залогинен, нельзя под этим именем еще раз войти.
А если у него браузер упадет, или там венда, сколько времени он должен после перезапуска куковать в ожидании, что его опять назад пустят?
Я бы не стал так делать. Если неприменно хочется ограничить, в каком количестве пользователь может присутствовать на сайте, пусть лучше новый логин прерывает ранее открытую сессию.