PankovAlxndr
@PankovAlxndr
Fullstack web developer

Как правильно реализовать API?

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

Есть сайт(сервис) по предоставлению услуг, внутри сайта есть личный кабинет пользователя, с его историей заказов, статусами заказов, историей оплат и т.д.

необходимо сделать API, которым бы пользовалось android приложение.

Как я начал делать, при авторизации с приложения делаю запрос к API такого плана:
/api/?user.checkAuth={"login":"admin", "pass":"md5('.....)"} проверяю правильный ли хеш,

А дальше генерирую случайную строку и сохраняю ее на сервере в паре СТРОКА - ПОЛЬЗОВАТЕЛЬ, так же отсылаю ее в ответ приложению, те эдакий сессионный токен, который знаю я, и знает приложение.

Далее приложение запрашивает список заказов, передавая мне только то, что знает: те токен, который я выдал при авторизации,:
запрос на список заказов:
/api/?user.getUserOrders={"token":"29db74ae5302f6fafa75428ada7f1871"}

на стороне сервера я принимаю токен, смотрю есть ли такой токен вообще к какому пользователю он привязан, и если все окей, то возвращаю JSON с заказами.

Тут первый вопрос, я двигаюсь в правильном направлении? и вытекающая проблема из текущей реализации:

1) есть у пользователя телефон и планшет с приложением
2) он авторизовался на телефоне - получил токен - пользуется
3) заходит с планшета - получает токен, КОТОРЫЙ ПЕРЕЗАПИСЫВАЕТСЯ если уже привязан к какому-то пользователю - пользуется.
вот тут и проблема, теперь если пользователь зайдет со своего телефона в приложение и попытается что-то запросить, передав токен с который сохранен в телефоне, то этот токен мы уже не найдем(тк перезаписали пару пользователь-токен при авторизации с планшета) и соответственно кинем его на страницу авторизации, для получения токена... и так до бесконечности, пользователь может работать только с 1ого устройста...

Как решить эту проблему, те сохранить безопасность, работая с токенами, и дать пользователю возможность иметь несколько токенов?

Чем-то грозит реализация, такая, что один user_id может иметь несколько токенов?

Как организовать сброс этих токенов и нужен ли он?

Заранее благодарен за помощь.
  • Вопрос задан
  • 8326 просмотров
Пригласить эксперта
Ответы на вопрос 6
zoonman
@zoonman
⋆⋆⋆⋆⋆
Шаг 1, изучаем https://jwt.io/ - на настоящий момент стандарт для аутентификации.
Шаг 2. Каждое устройство должно иметь уникальный токен. Пользователь должен иметь возможность деавторизовать любое устройство. При смене пароля все токены автоматически стираются.

Организация хранения токена должна выглядеть примерно так:
tokens
- user_id
- device_id  - при авторизации через браузер можно подставить md5(User-Agent)
- device_name  - человеко-понятное имя девайса или название браузера
- token
- last_used
- expires_at

Про API, вместо передачи дополнительного параметра в запросе очень часто используют HTTP-заголовки.
Наличие множества токенов практически ничем не грозит, разве что небольшим увеличением размера данных.
Сброс токенов нужен по времени, по смене пароля, значительной смене географии (другая страна и т.п.), при нажатии кнопки Выход и по желанию пользователя (опции Выйти со всех устройств).
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Ответ написан
Комментировать
e_svirsky
@e_svirsky
Web Developer
я бы сделал так:
OAuth авторизацию между андроидом и серваком. Уникальность проверять по ID device-а.
REST api для получения данных.

При такой авторизации - не будет слетать токен при попытке авторизоваться с другого девайса.
Ответ написан
Комментировать
@peacemakerv
Разработка под Android
Например, так: pmaker.biz/server-api-sample-for-client-development
Уникальность железки, кроме уникальность юзера, обеспечьте передачей и проверкой на сервере дополнительно параметра Android_ID клиента.
Ответ написан
Комментировать
Adamos
@Adamos
Как я начал делать, при авторизации с приложения делаю запрос к API такого плана:
/api/?user.checkAuth={"login":"admin", "pass":"md5('.....)"} проверяю правильный ли хеш,

А дальше генерирую случайную строку и сохраняю ее на сервере в паре СТРОКА - ПОЛЬЗОВАТЕЛЬ, так же отсылаю ее в ответ приложению, те эдакий сессионный токен, который знаю я, и знает приложение.


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

Чем-то грозит реализация, такая, что один user_id может иметь несколько токенов?

Стандартной ошибкой - если вы будете в чем-то полагаться на ту информацию, которую хранит приложение, а не сайт.
Например, если приложение при запуске загружает остаток средств на счете и потом оперирует этой цифрой, не проверяя, не был ли он за это время уже изменен на сайте.
Ответ написан
Комментировать
Acuna
@Acuna
Заполнил свой профиль
Чисто замечание по оформлению. Запросы на выборку, где просто присутствуют ключи per_page, limit и т. п., нужно передавать методом GET, содержащие длинные или личные данные - POST и другими, по ситуации. Необходимость этого в том, что GET передает данные просто в адресной строке браузера (это очевидно), POST передает их по шифрованному туннелю (если, конечно, Вы поднимите шифрование, иначе и смысла не будет, через консоль разраба Хрома их можно вытащить в миг). Плюс ограниченная длина: у GET ограничена строкой браузера, у POST и прочих хоть книгу передавайте. Нативный cURL из коробки работает со всеми методами.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы