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

Я немного не уверен, как лучше всего это сделать, я провел некоторые исследования, и can oAuth упоминался несколько раз, наряду с базовой аутентификацией через HTTPS.

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

  1. на главной странице мобильного приложения пользователь правильно входит в систему со своим именем пользователя и паролем , и это отправляет запрос в API.
  2. это возвращает успешный ответ (показано выше) с текущей меткой времени и всем важным токеном.
  3. тот же пользователь переходит на другую страницу приложения/представление, где этот токен a) требуется и b) если он соответствует этому аутентифицирует этого пользователя (e.g, чтобы они могли редактировать эту учетную запись и т. д..)
  4. как только пользователь нажимает "Выход" этот токен затем удаляется (и может дольше получать доступ к моей учетной записи и т. д..)- по существу система аутентификации на основе токенов.

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

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

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

3 ответов


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

Focus решение, которое обеспечивает все хорошие (RESTful) auth вещи сразу, что, вероятно, будет:

  • протокол SSL (самое главное, иначе "HTTP-Auth" будет меньше, каждый сможет прочитать ваш заголовок / тело запроса человек-в-середине атаки)
  • протокол OAuth (или лучше что OAuth2!)
  • HTTP-Auth
  • маркеры (включая ограниченный срок службы, обновить и, возможно, включить логику проверки IP/DeviceUID - > если это мобильный!)
  • соль генерируемые пароли
  • пользовательские HTTP-заголовки для ID/ENV / CLIENT проверки или что-либо еще.
  • зашифрованные данные тела для запроса и ответа для предотвращения данных манипуляции

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


возможно, решение

выше вы можете увидеть стандартную информацию об интерфейсах безопасности. Чтобы обеспечить прочную безопасность, вы можете попробовать это, как в следующей части. Я не уверен насчет вашего AppSidePersitence. Может быть, его sqlLite или что-то в этом роде. Вот почему я не указываю кодовую DB-схему, как я это сделал с 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;

Ваш AppPersitenceModel

enter image description here

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

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

    * * 200 OK Ответ-пример, после успешного входа пользователя в систему, содержит вычисленную "истекшую" дату:**

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

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

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

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

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

    ** ответ 401 Unauthorized-например, пользователь не вошел в систему (не токен существует в YiiDB):**

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

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


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

EDIT: проверьте этот удивительный tut от плодовитого Фила осетра. У него также есть отличная библиотека CI для создания RESTful API в 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, и для дальнейшего использования самым чистым решением было бы использовать включенные классы для RESTful API, или можно реализовать их в любой структуре.

источник: HttpBearerAuth.в PHP

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