Авторизация и аутентификация REST API (web + mobile)
Я читал о oAuth, Amazon REST API, HTTP Basic / Digest и так далее, но не могу получить все это в "один кусок". Это, наверное, самая близкая ситуация - создание API для мобильных приложений-аутентификация и авторизация
Я хотел бы построить API-ориентированный сайт-сервис. Итак (в начале) у меня был бы API в центре и сайт (PHP + MySQL) будет подключаться через cURL,Android и iPhone через свои сетевые интерфейсы. Итак 3 основных клиента-3 ключа API. И любой другой разработчик также может развиваться через интерфейс API и они получат свой ключ API. Действия API будут приняты / отклонены на основе статуса userLevel, если я администратор, я могу удалить что-либо и т. д., все остальные могут манипулировать только своими локальными (учетными) данными.
во-первых, авторизация-должен ли я использовать oAuth + xAuth или мою собственную имплементацию (см. http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RESTAuthentication.html?r=9197)- Как я понимаю, на Амазонка пользователей сервиса == пользовательского API (есть ключ API). На моем сервисе мне нужно разделить обычных пользователей / учетную запись (тот, кто зарегистрировался на веб-сайте) и учетные записи разработчиков (у которых должен быть свой ключ API).
поэтому мне сначала нужно авторизация ключа API а то аутентификация пользователя сам по себе. Если я использую схему Amazon для проверки ключей API разработчика (авторизация их приложения), какой sheme я должен использовать для аутентификации пользователя?
Я читал о получении токена через api.example.org/auth
после (через HTTPS, HTTP Basic) размещение моего имени пользователя и пароля, а затем переслать его на каждый следующий запрос. Как управлять токенами, если я вошел в систему одновременно на Android и сайт? Как насчет man-in-the-middle-attack, если я использую SSL только по первому запросу (когда имя пользователя и пароль передаются) и просто HTTP на каждом другом? Разве это не проблема в этом примере Защита паролем службы REST?
1 ответ:
Как всегда, лучший способ защитить ключ, не передать его.
тем не менее, мы обычно используем схему, где каждый "ключ API" имеет две части: несекретный идентификатор (например, 1234) и секретный ключ (например, байт[64]).
- если вы выдаете ключ API, храните его (соленый и хэшированный) в вас база данных сервиса.
- если вы выдаете учетные записи пользователей (защищенные паролем), сохраните пароли (соленые и хэшированные) в вашем сервисе база данных
теперь, когда потребитель первый доступ к вашему API, чтобы подключиться, у него
- отправить параметр " username "("john.лань " не секрет)
- отправить параметр " APIkeyID "("1234", не секрет)
и вернуть ему
- соли из вашей базы данных (в случае, если один из параметров неверен, просто верните немного повторимой соли-например. sha1 (имя пользователя+"notverysecret").
- в метка времени сервера
потребитель должен хранить соль для продолжительности сеанса, чтобы держать вещи быстро и гладко, и он должен рассчитать и сохранить смещение времени между клиентом и сервером.
теперь потребитель должен вычислить соленые хэши ключа API и пароля. Таким образом, потребитель имеет те же самые хэши для пароля и ключа API, что и то, что хранится в вашей базе данных, но без каких-либо seceret когда-либо идет по проводу.
теперь, когда потребитель subseqently доступ к вашему API, чтобы сделать реальную работу, у него
- отправить параметр " username "("john.лань " не секрет)
- отправить параметр " APIkeyID "("1234", не секрет)
- отправить параметр" RequestSalt " (байт[64], случайный, не секретный)
- отправить параметр" RequestTimestamp " (вычисляется из времени клиента и известного смещения)
- отправить параметр " RequestToken (хэш (passwordhash+request_salt+request_timestamp+apikeyhash))
сервер не должен принимать метки времени больше, чем говорят 2 секунды в прошлом, чтобы сделать это безопасным от повторной атаки.
теперь сервер может вычислить тот же хэш (passwordhash+request_salt+request_timestamp+apikeyhash), что и клиент, и убедитесь, что
- клиент знает ключ API,
- клиент знает правильный пароль