Архитектура модуля по работе с пользователями

Разговоры на любые темы: вы можете обсудить здесь какой-либо сайт, найти единомышленников или просто пообщаться...
ndemidov
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 14.11.2007 (Ср) 16:23
Откуда: Earth planet

Архитектура модуля по работе с пользователями

Сообщение ndemidov » 22.02.2016 (Пн) 8:54

Добрый день. Делаю сетевые шахматы. Испытываю проблемы в планировании архитектуры. Начал с модуля по авторизации, сделал классы AccountManager - для хранения и проверки на создание аккаунта\логина; класс ConnectionManager - для актуального ведения открытых каналов с аккаунтами.

Несколько вопросов:

:?: В каком виде отсылать сообщения клиенту? Скажем список он-лайн пользователей с их рейтингом, кол-вом побед, поражений, игр - в виде списка объектов User, или же лучше перегонять их в текстовый массив? - Просто в объекте User есть поле password - и в таком случае оно тоже передастся клиенту.

:?: Отсюда вытекает второй вопрос: может сделать так, чтобы класс AccountManager скрывал конфиденциальную инфу от всего остального кода? Но как такое сделать - обнулять поле Password перед "отдачей" его в своих public методах или хранить пароли не в классе User, а в другом классе? Как принято делать?

:?: Третий вопрос, наверно вряд ли получится понятно объяснить. Он звучит - как лучше сделать архитектуру класса\ов управляющих всеми и подключенными пользователями на сервере.
В данный момент у меня так:

_______________________
class AccountManager:
+ createNewUser (String userName, String password)
+ login (String userName, String password) - в случае успеха возвращает объект типа User
_______________________
class ConnetcionManager:
+ ConnetcionManager (IAccountManager accountManager) - конструктор принимает AccountManager
- updateConnection (Channel senderChannel, User user) - связывает канал с пользователем. Если связано, значит он онлайн, private метод.
+ createNewUser (String userName, String password, Channel senderChannel) - обертка для CreateNewUser
+ login (String userName, String password, Channel senderChannel) - обертка для Login. В случае успеха вызывает private метод updateConnection(). Таким образом нет никакого способа из других модулей добавить пользователя "онлайн", кроме как вызвать метод Login у ConnectionManager.
+ access (Channel senderChannel) - когда с какого-то канала приходит сообщение, мы вызываем этот метод. Он ищет канал и находит соответствующего пользователя, либо выкидывает ошибку. Таким образом мы проверяем - проходила ли процедура логина ранее с этого канала.
_______________________

Мне сложно продумать архитектуру... И как потом надо будет расширять функционал. До самих шахмат я так ещё и не дошел. Пока сделал только общий чат.
Так вот, вопрос по архитектуре всего этого:
:?: Не уверен вообще надо было разделять это на два класса... ConnetcionManager просто делает функции обертки для AccountManager. И при добавлении новых public методов (banByIP, banByLogin, updateUser) в AccountManager'е - придётся писать новые обертки и в ConnetcionManager. Как лучше сделать - объединить эти два класса в один, сделать наследованием, сделать внутренние\вложенные классы или как щас - оставить "разбитыми" на два разных класса?
Сейчас конструктор класса ConnetcionManager ожидает реализацию интерфейса IAccountManager - экземпляр класса AccountManager.
Последний раз редактировалось ndemidov 22.02.2016 (Пн) 16:05, всего редактировалось 7 раз(а).
Большинство людей не понимает, что великое многообразие и красочность мира будут служить им крепчайшей душевной поддержкой на протяжении всей жизни. Иван Ефремов

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Архитектура модуля по работе с пользователями

Сообщение Debugger » 22.02.2016 (Пн) 12:20

По первым двум вопросам: всё выглядит так, будто тебе надо сделать отдельный класс, представляющий собой User'а, переденного по сети. Какой-нибудь UserProfile. В простейшем случае у тебя UserProfile будет отличаться от User только отсутствием пароля; в UserProfile также можно хранить только агрегированные характеристики для экономии трафика.

ndemidov
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 14.11.2007 (Ср) 16:23
Откуда: Earth planet

Re: Архитектура модуля по работе с пользователями

Сообщение ndemidov » 22.02.2016 (Пн) 13:54

А лучше "перегонять" в UserProfile непосредственно перед отправкой на клиент?
Или же чтобы класс AccountManager уже отдавал бы объекты только типа UserProfile - и все остальные классы (включая ConnectionManager) будут работать только с UserProfile?

Еще немного беспокоит вопрос о затратности процесса "перегонки" на память и скорость. И в классах AccountManager и ConnectionManager хранятся по несколько листов\map'ов для более быстрого доступа, это напрягает, опять я недопланировал это все
Большинство людей не понимает, что великое многообразие и красочность мира будут служить им крепчайшей душевной поддержкой на протяжении всей жизни. Иван Ефремов

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Архитектура модуля по работе с пользователями

Сообщение Debugger » 22.02.2016 (Пн) 17:11

ndemidov писал(а):А лучше "перегонять" в UserProfile непосредственно перед отправкой на клиент?

Да, верно: сервер перегоняет User в UserProfile перед отправкой; и клиент уже принимает и отображает на формочке UserProfile.

ndemidov писал(а):Еще немного беспокоит вопрос о затратности процесса "перегонки" на память и скорость.

Преждевременная оптимизация - корень всех зол (Д. Кнут).

ndemidov писал(а):Таким образом нет никакого способа из других модулей добавить пользователя "онлайн", кроме как вызвать метод Login у ConnectionManager.

Пока не налетели остальные гуру и не разбомбили проект и твой энтузиазм: определись, зачем тебе нужен проект.

Если ты хочешь попробовать аккуратно спроектировать архитектуру, то открывай какой-нибудь Visual Paradigm, бери книжку по архитектуре (я бы даже посоветовал по паттернам книжку "Design Patterns: Elements of Reusable Object-Oriented Software", она дает представление как классы должны взаимодействовать, а как - нет) и рисуй всевозможные диаграммы, пробуй разные варианты декомпозиции. Возможно, ты не напишешь даже и строчки кода (но все же стоит, чтобы понять, что не забыл каких-то мелочей) - но цели достигнешь. Кстати, проектирование стоит начать с того, чтобы понять необходимый функционал и нарисовать GUI. Это, например, ответит на вопрос, нужен ли тебе UserProfile, или достаточно занулить password перед отправкой на сервер.

Если цель - получить конечный продукт (если это проект на заказ/конкурс/ну очень нужно), то примерный список требований и функционала у тебя и так уже есть, равно как и общее представление о конечном продукте. Есть эмперическое правило: код до ~10 тысяч строчек можно просто сесть и написать ("запинать ногами"), без документации и проектирования. Это не особо большой проект, и это именно такой случай. Пускай у тебя все поля и методы будут публичными, да. Не страшно, никто не умрет от этого (кроме человека, который это будет поддерживать, конечно). Получить что-то играбельное можно за сутки; проект же реально на неделю-другую.

ndemidov
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 14.11.2007 (Ср) 16:23
Откуда: Earth planet

Re: Архитектура модуля по работе с пользователями

Сообщение ndemidov » 22.02.2016 (Пн) 20:35

Спасибо!) несколько прояснилось.

Проект делаю как лабораторное задание - да, я опять (хотя всего второй раз) прохожу типо обучения в одной конторе. Теперь на java. Потратил две недели на получение азов о работе с Netty (non-blocking I/O (NIO) client-server framework), пару дней на JavaFX и пр. Хотелось произвести впечатление))))

Пусть кто знает (а если гуру, то ещё лучше) "разносят" проект :) я научусь новому, это круто и лучше проясню ситуацию)
Большинство людей не понимает, что великое многообразие и красочность мира будут служить им крепчайшей душевной поддержкой на протяжении всей жизни. Иван Ефремов

ndemidov
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 14.11.2007 (Ср) 16:23
Откуда: Earth planet

Re: Архитектура модуля по работе с пользователями

Сообщение ndemidov » 26.02.2016 (Пт) 17:59

Еще пару вопросов:
1) Изначально думал, чтобы из класса AccountManager невозможно было получить объекты типа User, кроме как вызовом метода login.
Ещё думал, чтобы AccountManager уже возвращал объекты не User, а UserProfile какой-нибудь (типо без пароля).
Оба варианта - для сокрытия данных от остального кода. Но наверно смысла в этом нет... Тяжелая логика какая-то.

2) А что если перед чтением книг по паттернам предварительно "ввестись", посмотрев видео по ним типо такого? https://www.youtube.com/watch?v=S-RjiMA ... hZa9dc56k4
Большинство людей не понимает, что великое многообразие и красочность мира будут служить им крепчайшей душевной поддержкой на протяжении всей жизни. Иван Ефремов

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Архитектура модуля по работе с пользователями

Сообщение Debugger » 26.02.2016 (Пт) 19:09

ndemidov писал(а):Еще пару вопросов:
1) Изначально думал, чтобы из класса AccountManager невозможно было получить объекты типа User, кроме как вызовом метода login.
Ещё думал, чтобы AccountManager уже возвращал объекты не User, а UserProfile какой-нибудь (типо без пароля).
Оба варианта - для сокрытия данных от остального кода. Но наверно смысла в этом нет... Тяжелая логика какая-то.

Смысла в этом особого нет.

Я предложил ввести UserProfile как класс, который нужен исключительно для сериализации, отправки на сети и для просмотра профиля пользователя - исходя из того, что он может содержать какие-то дополнительные вычисляемые поля (типа количества игр и побед), которых User непосредственно может и не быть.

Сейчас ты по сути говоришь о том, что в классе User может и вовсе не быть пароля - он будет проверяться в недрах процедуры login, при обращении к БД. Или он где-то ещё используется? Если да, то где? Будет ли это передаваться по сети? Возможно, стоит хранить солёные хэши вместо пароля? Будет ли соединение будет защищенным? Будет ли редактирование профиля и смена пароля? Может, надо ещё какую-то функцию завести? Или имеющегося хватит? Поэтому надо сначала разобраться с требованиями, и как всё будет выглядеть, потом нарисовать интерфейс - и оставшееся проектирование станет простым и незатейливым.

ndemidov
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 14.11.2007 (Ср) 16:23
Откуда: Earth planet

Re: Архитектура модуля по работе с пользователями

Сообщение ndemidov » 20.03.2016 (Вс) 10:07

Можно сказать закончил основной функционал сетевых шахмат - можно рассылать приглашения, играть, есть проверка шаха, мата, пата, рокировка. Более сложную проверку правил - "взятие на проходе", учёт "мертвой позиции" выбор в какую фигуру превратить пешку по достижению конца доски (она просто превращается в ферзи) не особо успеваю.

Теперь есть время заняться доработкой. Почитал про солёные хэши в вики и на хабре. Какой из следующий вариантов предпочтительнее?
https://ru.wikipedia.org/wiki/Соль_(криптография)
https://habrahabr.ru/post/145648/

1)
Клиент:
1) хэшируем пароль
2) отправляем полученный хэш на сервер

Сервер:
1) генерируем случайную соль
2) второй раз хэшируем полученный хэш + соль
3) Сохраняем соль и последний полученный хэш

2)
Клиент:
1) генерируем случайную соль
2) хэшируем введенный пользователем пароль + соль
3) отправляем полученный хэш на сервер

Сервер:
1) Просто сохраняем полученный хэш

Я так понял, что оба варианта равноценны, так как неважно увидят соль или нет. Её предназначение - это ухудшить взлом всех пользователей в случае слива базы.
Большинство людей не понимает, что великое многообразие и красочность мира будут служить им крепчайшей душевной поддержкой на протяжении всей жизни. Иван Ефремов

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Архитектура модуля по работе с пользователями

Сообщение Debugger » 20.03.2016 (Вс) 16:21

Сервер генерирует соль, отправляет клиенту. Клиент засаливает пароль и хеширует, отправляет серверу. Сервер сверяет.

Если использовать только хеш, то сама идея хеширования пропадает: злоумышленнику достаточно перехватить хеш пароля, чтобы взломать аккаунт. Затея генерации соли на клиенте по той же причине бессмысленна.

Я бы посоветовал сначала написать саму игру, а потом уже обвешивать её интерфейсом и прочей криптографией.

Кстати, по теме: советую почитать бложик разработчика StarCraft: http://www.codeofhonor.com/blog/tough-t ... -starcraft

ndemidov
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 14.11.2007 (Ср) 16:23
Откуда: Earth planet

Re: Архитектура модуля по работе с пользователями

Сообщение ndemidov » 21.03.2016 (Пн) 9:50

Debugger писал(а):Сервер генерирует соль, отправляет клиенту. Клиент засаливает пароль и хеширует, отправляет серверу. Сервер сверяет.

Если использовать только хеш, то сама идея хеширования пропадает: злоумышленнику достаточно перехватить хеш пароля, чтобы взломать аккаунт. Затея генерации соли на клиенте по той же причине бессмысленна.


Не совсем понял:
- Если сервер достает ранее сгенерированную соль из БД для пользователя. То есть она всегда с сервера приходит одинаковая для юзера А. То злоумышленник также может перехватить хеш.
- Если же сервер каждый раз генерирует случайную соль, и отправляет ее на клиент, то как сравнить полученный с клиента кеш с тем который лежит в БД (в последнем не будет этой случайно соли)...


Мне ещё не понятно - если мы хешируем пароль на клиенте (так же безопаснее для передачи по сети), то как на сервере проверить, чтобы пароль был не меньше n символов и содержал допустимые символы?
Большинство людей не понимает, что великое многообразие и красочность мира будут служить им крепчайшей душевной поддержкой на протяжении всей жизни. Иван Ефремов

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Архитектура модуля по работе с пользователями

Сообщение Debugger » 21.03.2016 (Пн) 17:34

ndemidov писал(а):
Debugger писал(а):Сервер генерирует соль, отправляет клиенту. Клиент засаливает пароль и хеширует, отправляет серверу. Сервер сверяет.

Если использовать только хеш, то сама идея хеширования пропадает: злоумышленнику достаточно перехватить хеш пароля, чтобы взломать аккаунт. Затея генерации соли на клиенте по той же причине бессмысленна.


Не совсем понял:
- Если сервер достает ранее сгенерированную соль из БД для пользователя. То есть она всегда с сервера приходит одинаковая для юзера А. То злоумышленник также может перехватить хеш.
- Если же сервер каждый раз генерирует случайную соль, и отправляет ее на клиент, то как сравнить полученный с клиента кеш с тем который лежит в БД (в последнем не будет этой случайно соли)...


Мне ещё не понятно - если мы хешируем пароль на клиенте (так же безопаснее для передачи по сети), то как на сервере проверить, чтобы пароль был не меньше n символов и содержал допустимые символы?


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

Лучше дать серверу возможность попросить прибавить к паролю соль, захешировать и передать результат. При этом на сервере должен быть пароль (/хеш пароля), и соль, чтобы сверить результат, отправленный клиентом с тем, что должно получиться. Откуда там возьмется пароль/хэш? При регистрации. Там-то и надо проверять валидность пароля.

ndemidov
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 14.11.2007 (Ср) 16:23
Откуда: Earth planet

Re: Архитектура модуля по работе с пользователями

Сообщение ndemidov » 19.04.2016 (Вт) 9:31

Дописал, вот ссылка на github): https://github.com/n-demidov/NetChess
Было бы круто узнать как можно улучшить разные аспекты, особенно архитектуру и пр.
Большинство людей не понимает, что великое многообразие и красочность мира будут служить им крепчайшей душевной поддержкой на протяжении всей жизни. Иван Ефремов


Вернуться в Народный треп

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14

    TopList  
cron