- PVSM.RU - https://www.pvsm.ru -
Представим, что перед вами стоит задача организовать аутентификацию [1] пользователя (в мобильном приложении, в первую очередь) так, как это сделано в Telegram/Viber/WhatsApp. А именно реализовать в API возможность осуществить следующие шаги:
Я постараюсь кратко изложить выработанный подход к этому вопросу. Подразумевается, что у вас API, HTTPS и, вероятно, REST [2]. Какой у вас там набор остальных технологий неважно. Если интересно — добро пожаловать под кат.
В сущности требуется добавить два добавить три метода в ваше API:
Действие соответствует CREATE в CRUD [3].
POST /api/sms_authentications/
Параметры на вход:
phone
Параметры на выход:
token
Если всё прошло, как ожидается, возвращаем код состояния [4] 200.
Если же нет, то есть одно разумное исключение (помимо стандартной 500 ошибки при проблемах на сервере и т.п. — некорректно указан телефон. В этом случае:
HTTP код состояния: 400 (BAD_REQUEST), в теле ответа: PHONE_NUMBER_INVALID.
Действие соответствует UPDATE в CRUD [3].
PUT /api/sms_authentications/<token>/
Параметры на вход:
sms_code
Аналогично. Если всё ок — код 200.
Если же нет, то варианты исключений:
PUT /api/sms_authentications/<token>/resend
Аналогично. Если всё ок — код 200.
Если же нет, то варианты исключений:
Помимо этого, каждый метод API, который требует аутентифицированного пользователя должен получать на вход дополнительный параметр token
, который связан с пользователем.
Литература:
Вам потребуется хранить специальный ключ для проверки СМС-кодов. Существует алгоритм TOTP [7], который позволяет, цитирую Википедию:
OATH-алгоритм создания одноразовых паролей для защищенной аутентификации, являющийся улучшением HOTP (HMAC-Based One-Time Password Algorithm). Является алгоритмом односторонней аутентификации — сервер удостоверяется в подлинности клиента. Главное отличие TOTP от HOTP это генерация пароля на основе времени, то есть время является параметром[1]. При этом обычно используется не точное указание времени, а текущий интервал с установленными заранее границами (например, 30 секунд).
Грубо говоря, алгоритм позволяет создать одноразовый пароль, отправить его в СМС, и проверить, что присланный пароль верен. Причём сгенерированный пароль будет работать заданное количество времени. При всём при этом не надо хранить эти бесконечные одноразовые пароли и время, когда они будут просрочены, всё это уже заложено в алгоритм и вы храните только ключ.
Пример кода на руби, чтобы было понятно о чём речь:
totp = ROTP::TOTP.new("base32secret3232")
totp.now # => "492039"
# OTP verified for current time
totp.verify("492039") # => true
sleep 30
totp.verify("492039") # => false
Существует масса реализацией этого алгоритма для многих языков: для Ruby [8] и Rails [9], для Python [10], для PHP [11] и т.д. [12].
Итого, в модели (или в таблице БД, если угодно) надо хранить:
В случае Android полученный токен можно хранить в SharedPreferences [15], а для iOS в KeyChain [16]. См. обсуждение на SoF [17].
Вышеописанный подход позволит вам в рамках вашего стека технологий реализовать указанную задачу. Если вас есть соображения по этому подходу или альтернативные подходы, то прошу поделиться в комментариях. Аналогичная просьба, если у вас есть примеры документации к безопасным системам хранения в других мобильных ОС.
Автор: mpetrunin
Источник [18]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ruby/156363
Ссылки в тексте:
[1] аутентификацию: https://ru.wikipedia.org/wiki/%D0%90%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F
[2] REST: https://ru.wikipedia.org/wiki/REST
[3] CRUD: https://ru.wikipedia.org/wiki/CRUD
[4] код состояния: https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2_%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D1%8F_HTTP
[5] https://core.telegram.org/methods: https://core.telegram.org/methods
[6] http://stackoverflow.com/questions/12401255/sms-registration-like-in-the-mobile-app-whatsapp: http://stackoverflow.com/questions/12401255/sms-registration-like-in-the-mobile-app-whatsapp
[7] TOTP: https://ru.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm
[8] Ruby: https://github.com/mdp/rotp
[9] Rails: https://github.com/heapsource/active_model_otp
[10] Python: https://github.com/pyotp/pyotp
[11] PHP: https://github.com/Spomky-Labs/otphp
[12] т.д.: https://github.com/search?utf8=%E2%9C%93&q=totp
[13] этой для Rails: https://github.com/joost/phony_rails
[14] SecureRandom: http://ruby-doc.org/stdlib-2.1.2/libdoc/securerandom/rdoc/SecureRandom.html
[15] SharedPreferences: http://developer.android.com/reference/android/content/SharedPreferences.html
[16] KeyChain: https://developer.apple.com/library/mac/documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html
[17] SoF: http://stackoverflow.com/questions/10146996/how-do-i-set-up-persistent-authentication-in-a-mobile-app
[18] Источник: https://habrahabr.ru/post/305694/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.