Вопросы по созданию веб-API с сессиями
Я пытаюсь сделать бэкэнд API веб-сайта (я хочу сделать бэкэнд независимым от внешнего интерфейса, поэтому пока я делаю только API на стороне сервера, максимально соблюдая RESTfulness). Я не делал этого раньше, поэтому я не знаю о "лучшем" и наиболее безопасном способе сделать что-то.
Как я это делаю сейчас:
Некоторые части API должны быть доступны только для определенного пользователя после входа в систему и до 24 часов спустя.
Для этого я генерирую случайный идентификатор сеанса всякий раз, когда пользователь входит в систему (я использую логин без пароля, поэтому пользователю назначается этот идентификатор, когда он щелкает ссылку в своем электронном письме) на стороне сервера, который отвечает отправкой этого сообщения. идентификатор сеанса для клиента один раз. Затем клиент сохраняет этот идентификатор сеанса в localstorage (или файл на диске, если клиент не является веб-браузером).
Затем я сохраняю этот идентификатор вместе со связанной электронной почтой в моей БД (таблица MySQL) на стороне сервера.
Теперь каждый раз, когда клиент хочет получить что-то от моего API, он должен предоставить адрес электронной почты и идентификатор сеанса в URL (пока я не хочу куки), который сервер проверяет по сравнению с данными в БД, если они существуют, тогда сервер отвечает полностью, иначе отвечает с ошибкой.
Через 24 часа сервер удаляет пару почтового идентификатора / идентификатора сеанса, и пользователь должен снова войти в систему (чтобы создать другой идентификатор сеанса и связать его со своей электронной почтой).
Теперь вопросы:
Безопасен ли мой метод или есть очевидные уязвимости? Есть ли другой проверенный способ, о котором я не знаю?
Есть ли лучший способ для клиента сохранить идентификатор сеанса (если он веб-браузер)?
Каков наилучший способ создания уникального идентификатора сеанса? В настоящее время я генерирую случайную 16-символьную строку, которую я устанавливаю в качестве первичного ключа таблицы сеанса электронной почты.
Является ли использование таблицы MySQL наиболее эффективным / наилучшим способом хранения идентификаторов сеансов (если они будут запрашиваться при каждом запросе)?
Нужно ли каким-либо образом шифровать идентификаторы сессии? Безопасно ли для клиента отправлять его в виде "пустого" URL-параметра?
Извините за слишком много вопросов в одном посте, но я думаю, что они связаны одним сценарием выше. Если это что-то меняет, я использую F# и ожидаю, что моим клиентом будет приложение для Android или веб-приложение.
1 ответ
Ваш REST API НЕ ДОЛЖЕН ничего знать о сеансе клиента REST, даже об идентификаторе сеанса. Если вы не хотите отправлять пароль при каждом запросе, все, что вы можете сделать, это подписать идентификатор пользователя и тайм-аут, чтобы служба могла аутентифицироваться на основе подписи. Используйте веб-токен JSON: https://en.wikipedia.org/wiki/JSON_Web_Token
Вы можете иметь клиент REST на стороне сервера, который может иметь сеанс, который вы описали. Вопрос в том, стоит ли усилий по разработке REST-сервиса вместо обычного веб-приложения? Я не уверен в вашем случае, но обычно ответ отрицательный, потому что у вас не будет стороннего REST-клиента, а у вашего приложения недостаточно трафика, чтобы оправдать многоуровневую архитектуру, или он недостаточно велик для разделения на несколько процессов., так далее...
Если безопасность важна, тогда вы ДОЛЖНЫ использовать настоящий алгоритм случайного генератора или аппаратное обеспечение. https://en.wikipedia.org/wiki/Random_number_generation Отправка чего-либо через HTTP небезопасна, вместо этого вы должны использовать HTTPS. Вы ДОЛЖНЫ использовать стандартный заголовок авторизации вместо параметра запроса. https://en.wikipedia.org/wiki/Basic_access_authentication