@ber_enot
Веб-разработчик, Vue.js / Node.js

Как использовать токены для аутентификации в API?

Здравствуйте.

Пишу RUSTful API на php, застрял на аутентификации с помощью сессий. Алгоритм у меня такой:
1. Клиент посылает login, RSA(pass)
2. Сервер расшифровывает пароль, хеширует, сравнивает в БД, в случае неудачи отправляет ошибку клиенту.
3. ?? Сервер генерирует случайный идентификатор сессии, записывает в бд (поля - user_id, sid, expired)
на данном шаге не совсем понимаю, какое время жизни сессии нужно задать
4. Сервер посылает клиенту sid и expired, т.е. индентификатор сессии и время жизни в секундах.
5. При последующих запросах клиент посылает в заголовке/в теле запроса sid.

Отсюда вопросы:
1. Как найти оптимальное время жизни сессии?
2. При запросах с текущим sid нужно ли увеличивать продолжительность жизни сессии?
3. В случае "гибели" сессии, клиент должен выполнить шаг 1 заново? (Тогда клиент должен постоянно хранить логин и шифрованный пароль, так?)
4. Как защитить sid от перехвата?

Прошу вашей помощи..
  • Вопрос задан
  • 23422 просмотра
Решения вопроса 1
bigton
@bigton
Web-программист
Как сделал я.

От классических сессий при работе через API отказался.

1. Для авторизации пользователь вводит логинпароль, устройство отправляет их по https на account/auth
2. account/auth выдает token (token_id:token_val) и secret
3. все дальнейшие запросы устройство отправляет по http указывая token и подписывая запросы с помощью secret

Как работает.

Сервер получает запрос, видит что пришел token, разбивает его через двоеточие на input_id и input_val. Выбирает из базы токен с пришедшим input_id, получает из базы значение token_val и secret. Сравнивает input_val и token_val. Если в базе нашелся токен с нужным id и значения val равны, пришло время проверить достоверность запроса.

Клиент помимо токена передал sign (подпись), которую сформировал так (например) secret+api_path+query_param. На стороне сервера вам известно api_path и api_param, а secret выбрали из базы. Хешировать подпись принято через hmac().

Помимо токена и подписи можно передавать time и так же класть его в sign, и на стороне сервера отсекать запросы запросы которым больше 60 сек.

Таким образом.

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

А в базе токены можете хранить пока клиент сам не запросит их уничтожения и сохранить время последного обращения через токен, и удалять токены которые не использовались более 60 дн.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
EvilsInterrupt
@EvilsInterrupt
System programming, Reversing Engineering, C++
Пишу RUSTful API на php, застрял на аутентификации с помощью сессий

Вы уверены что Вы понимаете что такое REST? Вы пишите что угодно, но не REST! Одно из требований к REST это stateless. Другими словами в Ваших запросах УЖЕ есть все необходимое для выполнения операции и тоже самое будет в ответе "либо приходи позже" либо "держи результат запроса на операцию". В REST нет такого термина, как сессия. Если у Вас это получилось, то вы написали не REST
Ответ написан
@matperez
Ответ написан
Комментировать
@kuftachev
Я так понимаю, что уже ответ не актуальный, но все-таки REST скорее подразумевает толстый клиент, по-этому состояние он хранить не должен. Yii2 умеет из коробки делать аутентификацию для REST, другие фреймворки, думаю, тоже.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы