Подтвердить что ты не робот

Внедрение аутентификации 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 обнаружен в любых последующих запросах, которые он примет в качестве аутентифицированного запроса (для этого пользователя "бобисмит" ).

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

Итак, вкратце это...

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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


Возможно решение

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

Ваш YiiDBModel

enter image description here

-- -----------------------------------------------------
-- 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

enter image description here

Обработка вашего маркера справа и обеспечение безопасности входа

  • Любой маркер, который вы создаете на стороне Yii-приложения, будет храниться с помощью "созданного" -Datetime в вашей YiiApp-базе данных (см. таблицу authToken). У каждого пользователя есть только один "токен", который будет создан после правильного "входа" -Request. Таким образом, вам не нужно проверять токены во время "входа". Определенный схемой, "токен" уникален! Я думаю, что нет необходимости обрабатывать исторические данные (старые токены, срок действия которых истек).
  • После того как пользовательский логин был подтвержден как "успех" от 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"
        }
    }
    
  • Важно: каждый запрос, который вы хотите защитить, должен быть отправлен с созданным пользователем "токеном". Скорее всего, это будет храниться в вашем устройстве. Вы можете обрабатывать свои "состояния входа" - действительно RESTful, если вы используете HTTP-Response-Codes, например, 200 OK (если все штраф) или 401 (не авторизовано, пользователь не зарегистрирован или сессия истекла). Вы должны подтвердить свой Пользовательский запрос на стороне Yii. Прочитайте токен из входящих запросов, подтвердите его из-за данных токенов в базе данных и сравните "созданный" -DB с текущим входящим запросом времени (HTTP-запросы).

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

    {
        "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
        }
    }
    
  • Сохранить сеанс пользователя? Это довольно просто. Просто обновите "created" -Date в authToken -Table до текущего времени запроса. Выполняйте это каждый раз, действительный запрос был отправлен пользователем. Таким образом, сеанс не истечет, если пользователь все еще активен. Убедитесь, что ваш токен-маркер не истек, перед обновлением поля expires -Date в БД. Если никакой запрос не будет отправлен во время истечения срока действия сеанса, сохранение будет невозможно.

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

Ответ 2

Если вы создаете собственное мобильное приложение, разумным было бы полагаться на безопасность собственной памяти (например, 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

Ответ 3

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

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

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