Создание токена доступа путем шифрования идентификатора пользователя + время как JSON

Я делаю API и Я новичок в этом. Я думал об этой идее для создания токена доступа. По сути, мы шифруем данные JSON ключом, превращаем их в Base64 и возвращаем в качестве маркера доступа. Позже API расшифровывает этот токен доступа и может использовать идентификатор. Например.:

login method:
мы проверяем правильность имени пользователя / пароля, если это так, то мы получаем идентификатор пользователя из базы данных. Затем мы создаем токен доступа, который будет использоваться в будущих вызовах API, например:

  1. мы создаем строку JSON, например {"user_id":609, "logintime":"1430428180"}
  2. мы используем функцию шифрования (например, эти) и зашифровать эту строку JSON, используя наш ключ шифрования.
  3. мы превращаем зашифрованную строку в Base64, чтобы она была читаемой и возвращала ее как маркер доступа.

Позже, когда пользователь совершает действие, мы можем использовать этот токен доступа, чтобы узнать о нем. Например.:

update user info method: мы отправляем данные, которые необходимо обновить, и токен доступа, который мы получили ранее. Тогда мы:

  1. Base64 расшифровать токен доступа.
  2. расшифруйте его, используя наш ключ шифрования.
  3. Проанализируйте данные JSON, и мы узнаем идентификатор пользователя, чтобы мы могли легко обновить базу данных. Кроме того, мы знаем, что вызов API допустим, потому что дешифрованная строка была JSON и содержала user_id а также logintime поля.

Этот подход хорош?

2

Решение

В этом ответе я собираюсь больше сосредоточиться на безопасности API, что, как мне кажется, является реальным вопросом, стоящим за этим вопросом (вызвано комментариями ОП в моем первом ответе).

Ключи API используются в тех случаях, когда вход пользователя затруднен, невозможен или нежелателен по другим причинам. Ключ API используется для Аутентификация, «доказательство того, кто я есть», часть доступа к API. авторизация, или «Мне разрешено делать это» обычно хранится на сервере.

Для того чтобы вы были удовлетворены тем, что запрос действителен, вы должны учесть пару моментов.

  1. Запрос поступил от авторизованного пользователя?
  2. Был ли запрос подделан в пути?

Чтобы убедиться, что точка 1 остается в силе с течением времени, API также должен быть обеспокоен тем, что секретный ключ остается секрет.

  1. Этот запрос не наносит ущерба действительности будущих запросов.

Обратите внимание, что хотя ключи API обычно отправляются в виде заголовков HTTP, я буду использовать переменные GET в моих примерах для простоты.

API единого ключа

Некоторые API настроены на предоставление доступа одним ключом. Давайте использовать CEgJu8G483u3 как наш пример ключа.

Пользователь отправил бы запрос как

GET /users?apiKey=CEgJu8G483u3 HTTP/1.1
Host: api.bigorg.com

Если API взаимодействует через HTTP, это по существу небезопасный:

  1. Ключ доступен для публичного чтения (и, следовательно, может использоваться) любой любопытной третьей стороной.
  2. Сторонняя сторона может изменять тело запроса сколько угодно, и сервер не знает об этом.

Таким образом, при аутентификации API по одному ключу по HTTP критерии безопасности 1 — 3 нарушаются.

Если ваш API-интерфейс с одним ключом связывается по HTTPS только, тогда 1 — 3 все еще действительны и могут считаться безопасными.

Дайджест или API подписи

Этот подход используется Google и Amazon для доступа ко многим их API.

Когда сервер предоставляет доступ к своей системе, два ключи сгенерированы, идентификатор и секрет.

ACCESS_IDENTIFIER = 'bill';
ACCESS_SECRET = 'U59g5LcBBZpw';

Как только два ключа были сгенерированы, клиент и сервер сохраняют копию секрета, которая никогда напрямую не передается.

Когда в этой системе делается запрос, идентификатор предоставляется вместе с запросом (обратите внимание, что ключ доступа может быть таким же сложным, как случайно сгенерированная строка, или таким же простым, как идентификатор пользователя, пытающегося получить доступ к системе.

Непосредственно перед отправкой запроса клиентом генерируется дайджест запроса, который затем шифруется с использованием ранее согласованного секрета. Способы генерации подписи могут быть разными, но в настоящее время распространенным является HMAC.

Запрос выглядит так

     GET /users?identifier=bill&signature=JjU1j1fIH62KG7FCTdZGzK7J HTTP/1.1
Host: api.bigorg.com

Случайная псевдоподпись, использованная в этом примере

Если тело запроса включено при создании подписи, теперь вы можете безопасно проходить аутентификацию.

Обратите внимание, что прослушивание HTTP-трафика все еще очень очень просто, поэтому неавторизованные знания все равно будут проблемой, но слушающая сторона не может отправлять свои собственные запросы или подделывать ваши.

Если запрос подделан, подпись становится недействительной, и запрос будет отклонен.

JSON Web Tokens (ваше решение)

Ваше решение почти идентично Веб-токены JSON, так что я просто сделаю вид, что ты это используешь.

Это решение защищено через HTTPS. (ДЕЛАТЬ использовать HTTPS)

  1. Запрос поступил от действительного пользователя => Они знали маркер
  2. Запрос не был подделан => HTTPS предотвращает вмешательство третьей стороны в запрос
  3. Ключ доступа остается секретным => HTTPS запрещает третьему лицу читать ваш ключ доступа

Если ваш API использует HTTP / открытый текст, вы можете использовать свои веб-токены JSON в качестве ключа доступа, но вам также нужно будет сгенерировать личный секрет и использовать его для добавления подписи в запрос.

Обратите внимание, что я не уверен, как вы передадите секрет клиенту, если вы используете HTTP. Может быть, по обычной или электронной почте?

Ваша идея была воспроизведена очень умными людьми. Поздравляем! Это значит, что это была хорошая идея!

Ваше решение ключа доступа является надежным при условии, что вы используете HTTPS.

10

Другие решения

Когда дело доходит до аутентификации, доступа к токенам, что у вас есть, вам, как правило, лучше использовать проверенную библиотеку, созданную кем-то намного умнее, чем мы оба.

Json Web Tokens или JWT, были созданы, чтобы решить именно такую ​​проблему (среди прочих). И это имеет библиотеку PHP.

Таким образом, создание токена доступа для пользователя будет выглядеть следующим образом. (Перефразируя файл Readme)

<?php

$key = "my-secret-key-here";
$token = array(
"user_id": 1
);

$jwt = JWT::encode($token, $key);

/**
* $jwt is your JSON web token, it will look something like this:
*
* eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMSJ9.TcXz_IwlmxO5nPd3m0Yo67WyYptabkqZW4R9HNwPmKE
*
**/

$decoded = JWT::decode($jwt, $key, array('HS256'));

print_r($decoded);

/*
NOTE: This will now be an object instead of an associative array. To get
an associative array, you will need to cast it as such:
*/

$decoded_array = (array) $decoded;

?>

Поэтому, отвечая на ваш вопрос, вы на правильном пути! JWT, кажется, делает именно то, что вы здесь описываете, поэтому я бы выбрал безопасность более тщательно протестированной библиотеки.

0

По вопросам рекламы [email protected]