Внедрение аутентификации RESTful API с использованием токенов (Yii / Yii2)

Я создаю API в Yii 1.x, который будет использоваться с мобильным приложением. Часть процесса включает логин (с именем пользователя и паролем), используя следующий JSON-запрос ниже:

// Запрос отправлен с именем пользователя и паролем

{ "request" : { "model" : { "username" : "bobbysmith", "password" : "mystrongpassword" } } } 

// Если успешно зарегистрирован в ответ, следующий ответ

 { "response": { "code": 200, "message": "OK", "model": { "timestamp": 1408109484, "token": "633uq4t0qdtd1mdllnv2h1vs32" } } } 

Этот токен очень важен – после входа пользователя в приложение я хотел бы, чтобы у них был доступ к другим страницам, для которых они должны быть зарегистрированы. Я хочу, чтобы мобильное приложение сохраняло этот токен и если тот же самый токен 633uq4t0qdtd1mdllnv2h1vs32 найденный в любых последующих запросах, он будет принимать это как аутентифицированный запрос (для этого пользователя «бобисмит»).

Я немного не уверен в том, как лучше всего это делать, я провел некоторое исследование и мог бы упомянуть оAuth несколько раз, а также Basic Authentication через HTTPS.

Так что в двух словах это …

  1. На домашней странице мобильного приложения пользователь регистрируется правильно со своим именем пользователя и паролем, и это отправляет запрос API.
  2. Это возвращает успешный ответ (показано выше) с текущей меткой времени и всем важным токеном.
  3. Тот же пользователь переходит на другую страницу / представление приложения, где этот токен a) требуется, и b) если он соответствует этому, он аутентифицирует этого пользователя (например, чтобы он мог редактировать эту учетную запись и т. Д.).
  4. Как только пользователь нажимает «Выход», этот токен затем удаляется (и может работать более длинный доступ к моей учетной записи и т. Д.) – по существу, система проверки подлинности на токенах.

Может ли кто-нибудь объяснить лучший способ достичь этого? Пожалуйста, дайте мне знать, если то, что я сказал, не является 100% ясным, и я предоставил больше информации.

В то время как я использую PHP, решение Yii 1.x идеально подходит, поскольку это то, что использует текущий API.

Вкратце, приложение гарантирует, что каждый запрос на сервер включает в себя токен в полезной нагрузке или заголовке, чтобы этот токен можно было получить на каждом последующем сообщении, после того, как он вышел из системы, этот токен просто удален или установлен в null / empty

Информация о работе с интерфейсами безопасности

Сосредоточьте решение, которое предоставляет все хорошие (RESTful) файлы auth сразу, что, вероятно, будет:

  • SSL (самое ВАЖНОЕ, иначе «HTTP-Auth» будет меньше, каждый сможет прочитать ваш заголовок запроса / тело « Человек-в-середине атаки» )
  • oAuth (или лучше oAuth2!)
  • HTTP-Auth
  • Токены (в том числе ограниченное время жизни, обновление и, возможно, включение IP / DeviceUID check logic->, если оно мобильно!)
  • Соль сгенерировала пароли
  • Пользовательские HTTP-заголовки для проверки ID / ENV / CLIENT или когда-либо.
  • Зашифрованные данные тела для запроса и ответа для предотвращения манипуляций с данными

Подсказка: личные данные пользователя должны быть зашифрованы!


Может быть, решение

Выше вы можете увидеть стандартную информацию о интерфейсах безопасности. Чтобы обеспечить прочную защиту, вы можете попробовать это, как в следующей части. Я не уверен в вашей AppSidePeritence. Возможно, это sqlLite или что-то в этом роде. Вот почему я не указываю на основе кода DB-Schema, как я сделал это для Yii. В вашем приложении Yii (бэкэнд), а также внутри вашего приложения (клиента) вам потребуется хранилище / постоянство для хранения времени и токенов.

Ваш YiiDBModel

введите описание изображения здесь

 -- ----------------------------------------------------- -- Table `mydb`.`user` -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `mydb`.`user` ( `id` INT NOT NULL, `username` VARCHAR(255) NOT NULL, `password` VARCHAR(255) NOT NULL, `lastLogin` DATETIME NULL, `modified` DATETIME NULL, `created` DATETIME NULL, PRIMARY KEY (`id`)) ENGINE = InnoDB; ---------------------------------------------------- -- Table `mydb`.`authToken` -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `mydb`.`authToken` ( `id` INT NOT NULL, `userId` INT NOT NULL, `token` VARCHAR(255) NOT NULL, `created` DATETIME NOT NULL, PRIMARY KEY (`id`, `userId`), INDEX `fk_authToken_user_idx` (`userId` ASC), UNIQUE INDEX `token_UNIQUE` (`token` ASC), CONSTRAINT `fk_authToken_user` FOREIGN KEY (`userId`) REFERENCES `mydb`.`user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB; 

Ваш AppPeritenceModel

введите описание изображения здесь

Правильная обработка маркера и обеспечение безопасности входа в систему

  1. Любой токен, который вы создаете на стороне Yii-приложения, будет храниться с «созданным» -Datetime в вашей YiiApp-базе данных (см. Таблицу authToken). У каждого пользователя есть только один «токен», который будет создан после правильного «входа» -Request. Таким образом, вам не нужно проверять токены во время «входа». Определенный схемой, «токен» уникален! Я думаю, что нет необходимости обрабатывать исторические данные (старые токены, срок действия которых истек).
  2. После того, как пользователь-логин был утвержден как «успех» Yii, вы создаете новый токен пользователя с текущей меткой времени, которая будет храниться в вашей YiiApp-DB. В вашем YiiApp вам нужно настроить «время истечения», которое будет добавлено в текущую временную метку, например, если вы хотите использовать «отметки времени»: текущая временная метка: 1408109484 а ваше время истечения срока действия – 3600 (что 3600 с = 1 ч). Итак … ваше время истечения срока действия, которое будет отправляться через API, (1408109484+3600) . Btw. Подсказка: вам не нужно отправлять такие атрибуты, как "code": 200 . Коды ответов включены в ваши запросы / данные ответа-заголовка.

    ** 200 OK Response-Example, после того, как пользователь-логин прошел успешно, содержит рассчитанный «expired» -date: **

      { "error": null, "content": { "expires": 1408109484, "token": "633uq4t0qdtd1mdllnv2h1vs32" } } 
  3. Важно: каждый запрос, который вы хотите защитить, должен быть отправлен с вашим сгенерированным «токеном» пользователя. Скорее всего, это будет храниться в вашем устройстве. Вы можете обрабатывать свои «состояния входа» – действительно RESTful, если вы правильно используете HTTP-Response-Codes , например, 200 OK (если все в порядке) или 401 (не авторизован, пользователь не зарегистрирован или сеанс истёк). Вы должны подтвердить свой запрос пользователя на стороне Yii. Прочитайте токен из входящих запросов, подтвердите его из-за данных токенов в базе данных и сравните «созданный» -DB с текущим входящим запросом времени (HTTP-запросы).

    ** Request-Example, схема по умолчанию для любых запросов безопасности: **

     { "token": "633uq4t0qdtd1mdllnv2h1vs32" "content": { "someDataYouNeed" : null } } 

    ** 401 Несанкционированный ответ – пример, токен истек: **

     { "error": 1, // errorCode 1: token is expired "content": { "someDataYouNeed" : null } } 

    ** 401 Unauthorized Response-Example, пользователь не зарегистрирован (в YiiDB нет токена): **

     { "error": 2, // errorCode 2: user is not logged in "content": { "someDataYouNeed" : null } } 
  4. Сохранить сеанс пользователя? Это довольно легко. Просто обновите «created» authToken в authToken -Table до текущего времени запроса. Выполняйте это каждый раз, действительный запрос был отправлен пользователем. Таким образом, сеанс не истечет, если пользователь все еще активен. Убедитесь, что ваш токен-маркер не истек, до того, как обновление expires поле «Дать» в БД. Если никакой запрос не будет отправлен во время истечения срока действия сеанса, сохранение будет невозможно.

    Извините, но добавить PHP-коды будет слишком много.

Если вы создаете собственное мобильное приложение, разумным было бы полагаться на безопасность собственной памяти (например, keychain iOS), а не на основе cookie-решения. В противном случае, как вы описали, все прекрасно. Пока ваша полезная нагрузка отправляется через SSL, на самом деле не имеет значения, является ли токен в PUT или POST. Управление маркерами (т.е. время истечения срока действия) – это бизнес-решения, которые вы должны принять. Задний конец я бы сделал, когда вы описываете и удерживаете токен в своей базе данных и удаляете его, когда он по какой-то причине утрачивает силу, и возвращает сообщение в клиентское приложение, чтобы вернуть его обратно в учетные данные режима выхода / повторного запроса.

РЕДАКТИРОВАТЬ: Посмотрите на эту потрясающую игру из плодовитого Фила-осетра. У него также есть отличная библиотека CI для создания API RESTful в CI, на который стоит обратить внимание.

http://philsturgeon.uk/blog/2013/07/building-a-decent-api

http://code.tutsplus.com/tutorials/working-with-restful-services-in-codeigniter–net-8814

К этому времени, вероятно, вы перешли на Yii2, и для будущей ссылки самым чистым решением было бы использовать включенные классы для API RESTful, или их можно реализовать в любой среде.

Источник: HttpBearerAuth.php

Преимущества полностью объясняются в этой статье , но, чтобы обобщить, лучше использовать свое решение с заголовками запросов , поскольку параметры GET могут быть сохранены в журналах, а пароль Basic Auth можно легко перехватить, если вы не используете SSL (вы должны! )