У компании большой талант, а дизайн схемы вызова трехстороннего интерфейса действительно элегантен~~
У компании большой талант, а дизайн схемы вызова трехстороннего интерфейса действительно элегантен~~

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

При проектировании решения для вызова сторонних интерфейсов,Необходимо учитывать безопасность и удобство использования. Ниже представлен обзор одного из вариантов конструкции.,Это включает в себя использованиеAPIключ(Access Key/Secret Key)Аутентификацияи Установить адрес обратного вызова。

Обзор конструкции

1. Генерация ключей API: Создайте уникальную пару ключей API (AK/SK) для каждого стороннего приложения, где AK используется для идентификации приложения, а SK — для подписи и шифрования.

AK: Идентификатор ключа доступа, используемый для идентификации пользователя. SK: секретный ключ доступа, который используется пользователями для шифрования строки аутентификации и проверки строки аутентификации. SK должен храниться в секрете. Проверьте личность отправителя запроса, используя шифрование идентификатора ключа доступа/секретного ключа доступа.

2. Аутентификация интерфейса: При вызове интерфейса клиенту необходимо использовать AK и параметры запроса для генерации подписи и поместить ее в заголовок запроса или параметры для аутентификации.

3. Настройка адреса обратного вызова: Сторонние приложения предоставляют адреса обратного вызова для получения асинхронных уведомлений и результатов обратного вызова.

4. Дизайн API интерфейса: Спроектируйте URL-адрес интерфейса, метод HTTP, параметры запроса, формат ответа и другие детали.

Разделение полномочий

appID: уникальный идентификатор приложения.

Используется для идентификации вашей учетной записи разработчика, то есть: идентификатор пользователя. Вы можете добавить индекс в базу данных для облегчения быстрого поиска. То же самое. appId Может соответствовать нескольким appKey+appSecret,достижение авторитета

appKey: открытый ключ (эквивалент номера учетной записи)

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

appSecret: закрытый ключ (эквивалент пароля)

Ключ подписи используется вместе с appKey и его можно понимать просто как пароль.

токен: токен (срок действия истек)

Как использовать

  • При запросе авторизации со стороннего сервера,Добавьте AppKey и AppSecret (должны существовать на стороне сервера)
  • Сторонний сервер проверяет, записаны ли appKey и appSecret в базе данных и кеше.
  • Если да, сгенерируйте уникальную строку (токен) и верните ее серверу, а сервер вернет ее клиенту.
  • Каждый последующий клиентский запрос должен принести токен.

Почему существует такой механизм, как appKey + appSecret, который появляется парами?

Поскольку требуется шифрование, оно обычно используется для первой проверки (аналогично сценариям входа в систему). Используйте appKey (отметьте, какие разрешения вы хотите запросить) + appSecret (пароль, указывающий, что у вас действительно есть это разрешение), чтобы подать заявку на получение. токен, который мы часто используем. accessToken (обычно имеет срок действия), и каждый последующий запрос должен предоставлять accessToken, чтобы указать, что разрешение на проверку передано.

Теперь, когда существует единый идентификатор приложения, если для одного и того же бизнеса необходимо разделить разные разрешения, например для одной и той же функции, в некоторых сценариях требуются разрешения только на чтение, а в некоторых сценариях — разрешения на чтение и запись. Таким образом, предоставление appId и соответствующего секретного ключа appSecret не может удовлетворить спрос. В настоящее время учетные записи необходимо распределять на основе разрешений, обычно используются appKey и appSecret.

потому что appKey и appSecret Это учетные записи, которые появляются парами, тот же самый appId Может соответствовать нескольким appKey+appSecret,так Платформы разныеappKey+appSecretНазначайте разные разрешения для。

Можно сгенерировать две пары appKey и appSecret. один на удаление,один для чтения и письма,достижение данные Детальное секционирование. нравиться : appKey1 + appSecect1 Только разрешение на удаление но appKey2+appSecret2 Есть разрешения на чтение и запись… Таким образом вы можете установить соответствующие разрешения Отдайте его разным разработчикам. Настройка разрешений напрямую связана с appKey. Для ассоциации appKey Вам также необходимо добавить индекс базы данных, Удобный и быстрый поиск

Упрощенный сценарий:

Первый сценарий: Обычно используется для открытых интерфейсов.,как карта API,будет опущеноapp_idиapp_key,В настоящее время это эквивалентно трем равным,стать одним appId = appKey = appSecret。В этом режиме,приноситьapp_idЦель состоит в том, чтобы просто подсчитать, сколько раз определенный пользователь вызывает интерфейс.。

Второй сценарий: Когда каждый пользователь имеет один и только один набор конфигураций разрешений. можно удалить appKey,напрямуюapp_id = app_key,Каждому пользователю назначается одинappId+ appSecretэтого достаточно。

Вы также можете использовать подпись: Когда вызывающая сторона инициирует запрос к методу поставщика услуг, принесите (appKey, временную метку timeStamp, случайное число nonce, знак подписи). Подпись Можно использовать (AppSecret + Временная метка + случайное число) с использованием sha1、md5генерировать,После того как поставщик услуг получит,Сгенерируйте локальную подпись и сравните полученную подпись,если последовательно,Проверка прошла успешно

Процесс подписи

картина
картина

Правила подписи

1. Назначьте appId (идентификатор разработчика) и appSecret (ключ) разным абонентам.

Вы можете подать заявку онлайн непосредственно через платформу или получить ее непосредственно в автономном режиме. appId глобально уникален, каждый appId будет соответствовать клиенту, а ключ appSecret должен быть строго конфиденциальным.

2.присоединитьсяtimeStamp(Временная метка), исходя из текущего времени сервера, единица измерения — мс. , данные действительны в течение 5 минут

Временная Цель метки — облегчить DOS-атаки. Предотвращает перехват запроса и продолжение попыток запроса интерфейса. Настройки сервера Временная меткапорог, если время сервера уменьшать просить Временная метка превышает порог,Указывает тайм-аут подписи,Вызов интерфейса не удался.

3. Добавьте временный серийный номер nonce, который должен состоять не менее чем из 10 цифр, чтобы предотвратить повторную отправку в течение срока действия.

Случайное значение nonce в основном предназначено для увеличения вариативности Подпись.,Вы также можете защитить идемпотентность интерфейса,Одноразовый номер двух соседних запросов не может повторяться.,Если это будет повторено, это будет считаться дубликатом.,Вызов интерфейса не удался.

  • В интерфейсе запроса серийный номер используется только для реализации журнала, чтобы облегчить последующую проверку журнала.
  • Для интерфейсов управления необходимо проверять уникальность серийного номера в течение срока действия, чтобы избежать повторных запросов.

Путем добавления параметров запроса подписи интерфейса Временная меткаtimeStamp + случайное число может предотвратить «Атака повтора»

  1. Временная метка(timeStamp):

На основе текущего времени сервера,Серверу требуется Временная метка, отправленная клиентом.,Должно быть в течение последних 60 секунд (предполагаемое значение,определяете сами).

Таким образом, даже если запрос будет перехвачен, повторная атака может быть осуществлена ​​только в течение 60 секунд.

  1. Случайное число (nonce):

но,Даже если установлена ​​Временная метка, у атакующего еще есть 60 секунд на атаку!

Поэтому нам нужно добавить случайное число в клиентский запрос (хакер не может изменить случайное число самостоятельно, поскольку происходит проверка подписи параметра. Сервер проверит запрошенное случайное число в течение одной минуты, если есть два одинаковых). по сути, их можно расценивать как повторные атаки.

Потому что при нормальных обстоятельствах количество двух одинаковых одноразовых номеров, генерируемых непрерывно за короткий период времени (например, 60 с), почти равно 0.

Сервер делает следующее, когда получает этот nonce «впервые»:

  1. Перейдите в Redis, чтобы узнать, есть ли данные с ключом nonce:{nonce}.
  2. если не,Затем создайте этот ключ,Установите время истечения срока действия ключа и убедитесь, что время истечения срока действия временной метки соответствует.,Например, это 60-е годы.
  3. Если да, это означает, что ключ использовался в течение 60 с, тогда запрос можно расценивать как запрос на воспроизведение.

4. Добавьте знак поля подписи, чтобы получить информацию о подписи, передаваемую вызывающим абонентом.

Путем добавления параметров запроса подписи интерфейса Временная меткаappId + sign Разрешить аутентификацию и предотвратить «Вмешательство в параметры»

  1. Запрос несет параметр appIdиSign,Только те, у кого есть идентификатор приложения, подтверждающий юридическую личность, и правильная подпись, могут быть освобождены. Это решает проблему аутентификации и подделки параметров.
  2. Несмотря на то Параметры запросаугнан,потому что невозможно получить appSecret (используется только для локального шифрования),не участвует в сетевой передаче),Также невозможно подделать законные запросы.

Вышеуказанные поля помещаются в заголовок запроса.

Дизайн интерфейса API

В зависимости от ваших конкретных потребностей и бизнес-сценариев, вот простой пример API дизайна интерфейса:

1. Получить интерфейс списка ресурсов
  • URL: /api/resources
  • HTTP-метод: ПОЛУЧИТЬ
  • Параметры запроса:
    • page (необязательный): номер страницы
    • limit (необязательный): Ограничить количество на странице
  • ответ:
    • Код статуса успеха: 200 ОК.
    • Тело ответа: Возвращает массив списков ресурсов JSON.
2. Создать интерфейс ресурса
  • URL: /api/resources
  • HTTP-метод: POST
  • Параметры запроса:
    • name (необходимый): Имя ресурса
    • description (необязательный): Описание ресурса
  • ответ:
    • Код статуса успеха: 201 Создано.
    • Тело ответа: Возвращает идентификатор и другую информацию вновь созданного ресурса.
3. Обновить интерфейс ресурса
  • URL: /api/resources/{resourceId}
  • HTTP-метод: PUT
  • Параметры запроса:
    • resourceId (параметры пути, Необходимый): Идентификатор ресурса
    • name (необязательный): Обновлено имя ресурса
    • description (необязательный): Обновленное описание ресурса
  • ответ:
    • Код статуса успеха: 200 ОК.
4. Удалить интерфейс ресурса
  • URL: /api/resources/{resourceId}
  • HTTP-метод: УДАЛИТЬ
  • Параметры запроса:
    • resourceId (параметры пути, Необходимый): Идентификатор ресурса
  • ответ:
    • Код статуса успеха: 204 No Content

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

Для обеспечения безопасности можно принять следующие меры:

  • Используйте протокол HTTPS для передачи данных, чтобы защитить безопасность данных во время связи.
  • Использовать подпись AKи в запросе на аутентификацию,и подтвердите запрос,Верификация и аутентификация на стороне сервера,Для предотвращения незаконных запросов и атак повторного воспроизведения.
  • Зашифрованная передача конфиденциальных данных, например использование алгоритма шифрования TLS для шифрования конфиденциальных данных.

Выше представлен простой дизайн-план и Дизайн. интерфейса Примеры API. Конкретные детали реализации могут различаться в зависимости от потребностей проекта. В реальном развитии,Также рассмотрите обработку ошибок, Обработка. исключений、Логирование и т. д.

Предотвращение атаки повторного перевода Зашифрованная передача конфиденциальных данные — все это важные меры для защиты безопасности трехсторонних интерфейсов. Вот пример кода, показывающий, как реализовать эти функции.

Предотвращение атак повторного воспроизведения

Захватите сообщение и повторно отправьте его в целости и сохранности, если это платежный интерфейс.,Или покупка интерфейса приведет к убыткам,Поэтому для проверки запроса необходимо использовать механизм защиты от повтора.,нравиться Параметры запроса Добавить в началоtimestampВременная метка+nonce случайное число.

Атака повторного воспроизведения относится к поведению хакера, который получает данные запроса клиента и запрашивает соединение путем перехвата пакетов и многократной отправки запросов на сервер.

Временная метка(tamp) + цифровая подпись (подпись), То есть при каждой отправке запроса передаются еще два параметра, а именно: tamp и sign。

Целью цифровой подписи является обеспечение действительности запроса. Потому что подпись зашифрована,Только клиент и сервер знают метод шифрования и ключ (ключ),Поэтому третьи лица не могут его имитировать. Валидность запроса определяем по проверке признака,Если проверка подписи не пройдена, это будет расценено как недействительный запрос.,Верно обратное. но Цифровые подписи не предотвращают атаки повторного воспроизведения, поскольку хакер может захватить ваш тампон (без внесения каких-либо изменений), а затем отправить запрос. В это время необходимо разобраться с Временной метка для проверки.

Временная Роль метки — обеспечить своевременность запросов. Мы отправим последнюю запрошенную Временную метка сохраняется и при следующем запросе Временная будет сохранена дважды метка для сравнения. Если это запросило Временная меткаи То же, что и в прошлый раз, или меньше, чем в прошлый раз Временная метка,Этот запрос определен как устаревший.,неверный. Потому что в обычных обстоятельствах,Время второго запроса должно быть больше, чем последний раз.,Не может быть равно или меньше.

нравитьсяфрукты Исправлять Понятно Временная метка, чтобы уложиться в сроки, проверка знака не пройдет.

Примечание. Если клиент js, обязательно запутайте js-код и запретите щелчок правой кнопкой мыши и т. д.

1. Используйте Nonce и временную метку

Добавьте в запрос уникальный Nonce (случайное число) и Timestamp (Временная). метка),и включить его в расчет подписи. Когда сервер проверяет подпись,Можно проверить валидность NonceиTimestamp,И убедитесь, что запрос не воспроизводится повторно.

Предотвращение атак повторного Проверка — одна из очень важных мер безопасности в трехсторонних интерфейсах. Используйте Nonce (одноразовое случайное число) и Timestamp (Временная метка) в сочетании может эффективно Предотвращение атак повторного текст. Вот рекомендации по реализации этой функции:

Создать Nonce и Timestamp:

  • Nonce должен быть случайной уникальной строкой. Можно Используйте UUID или другой алгоритм генерации случайной строки для создания.
  • Временная метка представляет запрошенную Временную метка, обычно стандартная Unix Временная формат метки (в секундах).

Включайте NonceиTimestamp в каждый запрос:

  • Добавляйте сгенерированный NonceиTimestamp в качестве параметра в каждый запрос.,Его можно передать через параметры URL, заголовки или тела запроса.
  • Убедитесь, что NonceиTimestamp уникален и верен в каждом запросе.

Проверка на стороне сервера NonceиTimestamp:

  • После получения запроса на стороне сервера,Сначала проверьте корректность NonceиTimestamp.
  • Проверьте, использовался ли Nonce ранее. Если он использовался, это может быть атака повтора, и отклоните запрос.
  • Проверьте, находится ли временная метка в разумном диапазоне времени. Если она превышает заданный период действия, запрос считается недействительным.

Хранение и управление

  • Чтобы проверить, использовался ли Nonce, серверу необходимо сохранить использованный Nonce.
  • Можно использовать базу данных, кэш или другой метод постоянного хранения для управления состоянием Nonce.
  • Просроченные одноразовые номера необходимо регулярно очищать, чтобы хранилище не занимало слишком много ресурсов.

Установить срок действия:

  • Чтобы ограничить срок действия запроса, вы можете установить разумный период действия.
  • В соответствии с реальными потребностями и бизнес-сценариями,Выберите подходящий период действия,Например, минуты или часы.

проходить Используйте NonceиTimestampПриходить Предотвращение атак повторного воспроизведения,Сторонние интерфейсы можно защитить от вредоносных запросов на воспроизведение. Выше приведены рекомендации по реализации этой функции.,Однако конкретные методы реализации могут различаться в зависимости от приложения и стека технологий. Убедитесь, что меры безопасности разрабатываются и реализуются с учетом конкретных потребностей приложения и модели рисков.

2. Добавьте срок годности

Добавьте в запрос поле срока действия (например,,срок действия токена),и проверьте на стороне серверапроситьиз Временная Находится ли метка в пределах срока действия. Запросы, срок действия которых превышает срок действия, должны быть отклонены.

Перехватчик атак с защитой от несанкционированного доступа и повторного воспроизведения

Каждый HTTP-запрос,Вам нужно добавить параметр timestamp,Затем соедините временную метку и другие параметры для цифровой подписи. Обычно HTTP-запрос доходит до сервера менее 60 секунд.,Итак, после того, как сервер получит HTTP-запрос,Сначала оцените параметр Временная метка и сравните его с текущим временем.,Превышает ли он 60-е годы,Если оно превышено, это считается незаконным запросом.

Обычно,Воспроизведение с перехвата пакетовпросить Это занимает гораздо больше, чем Понятно60s,Таким образом, параметр timestamp в запросе в настоящее время недействителен.,Если вы измените параметр timestamp на текущую Временную метку,Тогда цифровая подпись, соответствующая параметру подписи, станет недействительной.,Потому что я не знаю ключа подписи,Невозможно создать новую цифровую подпись.

Но уязвимости этого метода также очевидны. Если атака повтора выполняется после 60 с, способа нет. Следовательно, этот метод не может гарантировать, что запрос действителен только один раз.

nonce означает случайную строку, которая действительна только один раз. Этот параметр должен быть разным для каждого запроса. Мы сохраняем параметр nonce каждого запроса в «наборе». При обработке HTTP-запроса мы сначала определяем, находится ли параметр nonce запроса в «наборе». Если он существует, он считается незаконным запросом.

Параметр nonce был сохранен в «коллекции» на сервере во время первого запроса. Повторные запросы будут распознаны и отклонены.

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

У этого метода также есть большая проблема: «набор», хранящий параметры nonce, будет становиться все больше и больше.

Одноразовый nonce может решить проблему 60-секундного параметра временной метки (Предотвращение повторного ударного сигнала), а временная метка может решить проблему того, что параметр nonce «set» становится все больше и больше.

Язык кода:javascript
копировать
public class SignAuthInterceptor implements HandlerInterceptor {

    private RedisTemplate<String, String> redisTemplate;

    private String key;

    public SignAuthInterceptor(RedisTemplate<String, String> redisTemplate, String key) {
        this.redisTemplate = redisTemplate;
        this.key = key;
    }

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        // получать Временная метка
        String timestamp = request.getHeader("timestamp");
        // Получить случайную строку
        String nonceStr = request.getHeader("nonceStr");
        // Получить подпись
        String signature = request.getHeader("signature");

        // Определить, превышает ли время xx секунд (Предотвращение атак повторного воспроизведения)
        long NONCE_STR_TIMEOUT_SECONDS = 60L;
        if (StrUtil.isEmpty(timestamp) || DateUtil.between(DateUtil.date(Long.parseLong(timestamp) * 1000), DateUtil.date(), DateUnit.SECOND) > NONCE_STR_TIMEOUT_SECONDS) {
            throw new BusinessException("invalid  timestamp");
        }

        // Определить, находится ли параметр nonceStr пользователя уже в Redis (чтобы предотвратить атаки повторного воспроизведения в течение короткого периода времени).
        Boolean haveNonceStr = redisTemplate.hasKey(nonceStr);
        if (StrUtil.isEmpty(nonceStr) || Objects.isNull(haveNonceStr) || haveNonceStr) {
            throw new BusinessException("invalid nonceStr");
        }

        // Подписать параметры заголовка запроса
        if (StrUtil.isEmpty(signature) || !Objects.equals(signature, this.signature(timestamp, nonceStr, request))) {
            throw new BusinessException("invalid signature");
        }

        // Сохраните параметр nonceStr, запрошенный этим пользователем, в Redis и настройте его автоматическое удаление через xx секунд.
        redisTemplate.opsForValue().set(nonceStr, nonceStr, NONCE_STR_TIMEOUT_SECONDS, TimeUnit.SECONDS);

        return true;
    }

    private String signature(String timestamp, String nonceStr, HttpServletRequest request) throws UnsupportedEncodingException {
        Map<String, Object> params = new HashMap<>(16);
        Enumeration<String> enumeration = request.getParameterNames();
        if (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement();
            String value = request.getParameter(name);
            params.put(name, URLEncoder.encode(value, CommonConstants.UTF_8));
        }
        String qs = String.format("%s×tamp=%s&nonceStr=%s&key=%s", this.sortQueryParamString(params), timestamp, nonceStr, key);
        log.info("qs:{}", qs);
        String sign = SecureUtil.md5(qs).toLowerCase();
        log.info("sign:{}", sign);
        return sign;
    }

    /**
     * Сортировать по алфавиту по возрастанию
     *
     * @param params Параметры запроса 。Уведомление Параметры запрос не может содержать ключ
     * @return Отсортированные результаты
     */
    private String sortQueryParamString(Map<String, Object> params) {
        List<String> listKeys = Lists.newArrayList(params.keySet());
        Collections.sort(listKeys);
        StrBuilder content = StrBuilder.create();
        for (String param : listKeys) {
            content.append(param).append("=").append(params.get(param).toString()).append("&");
        }
        if (content.length() > 0) {
            return content.subString(0, content.length() - 1);
        }
        return content.toString();
    }
}

Зарегистрируйте перехватчик, чтобы указать интерфейс перехвата.

Зашифрованная передача конфиденциальных данных

Использование протокола TLS (Transport Layer Security) может обеспечить шифрование и целостность данных во время процесса связи. Вот несколько основных шагов:

  • Настройте сертификат TLS (включая открытый и закрытый ключ) на сервере.
  • Между клиентом и сервером устанавливается TLS-соединение. Клиент отправляет HTTPS-запрос на сервер.
  • Во время установления связи TLS клиент и сервер согласовывают алгоритм шифрования и метод обмена ключами.
  • После успешного рукопожатия,Вся передача данных между клиентом и сервером будет зашифрована.

Конкретная реализация зависит от используемого языка программирования и платформы. Ниже приведен пример кода с использованием Java, который демонстрирует, как использовать TLS для зашифрованной передачи:

Язык кода:javascript
копировать
// Создать объект SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");

// Инициализируйте SSLContext, загрузите сертификат и закрытый ключ.
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(new FileInputStream("keystore.jks"), "password".toCharArray());

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "password".toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);

sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());

// Создать соединение HttpsURLConnection.
URL url = new URL("https://api.example.com/endpoint");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(sslContext.getSocketFactory());

// Установить другие параметры запроса、Отправить запрос、Обработка ответов и т. д.

В этом коде,Мы создаем объект SSLContext и инициализируем его.,Сертификат сервера и закрытый ключ загружены. Затем,проходитьHttpsURLConnectionобъект,Настройка безопасной фабрики сокетов для TLS,и установил HTTPS-соединение с указанным URL-адресом.

пожалуйста, обрати внимание,Вам необходимо заменить фактический сертификат и файл закрытого ключа (обычно в формате .jks) на реальный путь к файлу.,и укажите правильный пароль.

Приведенный выше код является простым примером,Фактическое развертывание может потребовать дополнительной настройки в зависимости от конкретных требований. Обеспечить соблюдение лучших практик и рекомендаций по безопасности в проекте.,И сотрудничать с соответствующими командами разработки и эксплуатации.,Для обеспечения безопасности стороннего интерфейса.

Схема генерации АК и СК

Для разработки трехстороннего интерфейса и предоставления его клиентам можно рассмотреть следующие методы генерации АК (Access Key)иSK(Secret Key):

Разработайте систему управления ключами API:

  • Создайте систему управления ключами API для генерации и управления AKиSK. Эта система может быть автономным серверным приложением или интегрирована с вашим основным приложением.

Сгенерировать АКи СК:

  • В системе управления ключами API,Сгенерируйте уникальный АКи СК для каждого клиента.
  • AK обычно является общедоступным идентификатором, используемым для идентификации клиента. Можно использовать, генерируемые случайными строками, UUID и т. д.
  • SK — секретный приватный ключ,Используется для создания подписей аутентификации и зашифрованных токенов доступа. Можно использовать, генерируемые случайными строками, хеш-функциями и т. д.,И убедитесь, что это достаточно безопасно.

*Хранение и управление АКи СК:

  • Сохраните сгенерированный AKиSK в базе данных или другом постоянном хранилище.,и связать ее с другой важной информацией о клиенте.
  • Необходимо внедрить соответствующие меры контроля разрешений и безопасности, чтобы гарантировать, что только авторизованные пользователи могут получить доступ и управлять AKиSK.
  • Вы можете рассмотреть возможность шифрования SK для повышения безопасности.

Предоставьте механизм распределения ключей API:

  • Клиенты могут использовать предоставленный вами интерфейс、APIИли самообслуживаниезарегистрироватьсяпроцесс Приходитьполучать他们изAKиSK。
  • во время раздачи,Обеспечьте безопасную доставку AKиSK клиентам. Например,Используйте зашифрованное соединение или другой безопасный канал для передачи.

Безопасность и лучшие практики:

  • Настоятельно рекомендуется провести аудит безопасности системы управления ключами API.,А также защищать и управлять АКи СК в соответствии с лучшими практиками.
  • Регулярно меняйте AKиSK, чтобы повысить безопасность и снизить потенциальные риски.
  • При проектировании интерфейса,Используйте AKиSK для аутентификации и контроля разрешений.,для предотвращения несанкционированного доступа.

пожалуйста, обрати внимание,Вышеуказанные шаги представляют собой общее руководство.,Конкретная реализация может варьироваться в зависимости от требований вашего приложения, технологического стека и стратегии безопасности. Обеспечьте соблюдение лучших практик безопасности,и обратитесь к соответствующей документации и рекомендациям по безопасности.,Обеспечить безопасность и надежность создаваемых АКи СК.

Язык кода:javascript
копировать
CREATE TABLE api_credentials (
    id INT AUTO_INCREMENT PRIMARY KEY,
    app_id VARCHAR(255) NOT NULL,
    access_key VARCHAR(255) NOT NULL,
    secret_key VARCHAR(255) NOT NULL,
    valid_from DATETIME NOT NULL,
    valid_to DATETIME NOT NULL,
    enabled TINYINT(1) NOT NULL DEFAULT 1,
    allowed_endpoints VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Эта таблица содержит следующие поля:

  • id: первичный ключ, самовозрастающий уникальный идентификатор.
  • app_id: идентификатор или идентификатор приложения, используемый для связи AKSK с конкретным приложением.
  • access_key: ключ доступа (AK), используемый для идентификации клиента.
  • secret_key: секретный ключ (SK), используемый для создания подписей и выполнения аутентификации.
  • valid_from: время начала действия AKSK.
  • valid_to: время окончания действия AKSK.
  • включено: включить ли AKSK, 1 означает включено, 0 означает отключено.
  • разрешенные_эндпоинты: список разрешенных интерфейсов/конечных точек, разделенных запятыми.
  • созданный_at: время создания записи.

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

пожалуйста, обрати внимание,Конкретная конструкция может варьироваться в зависимости от потребностей вашего приложения и сценариев использования. Прежде чем внедрять, убедитесь, что вы внимательно рассмотрели требования своего бизнеса.,И следуйте хорошим принципам проектирования баз данных и лучшим практикам.

Дизайн интерфейса APIПополнить

картина
картина
1. Используйте POST в качестве метода запроса интерфейса.

Обычно двумя наиболее распространенными способами вызова интерфейсов являются GET и POST. Разница между ними также очевидна,GET-запросы предоставляют параметры в URL-адресе браузера.,Также существует ограничение по длине. для большей безопасности,Все интерфейсы используют запрос POST.

2. Белый список IP-адресов клиентов

Белый список IP-адресов означает открытие прав доступа к интерфейсу для некоторых IP-адресов для предотвращения атак доступа с других IP-адресов.

  • Недостаток настройки белого списка IP-адресов заключается в том, что после миграции вашего клиента вам необходимо снова связаться с поставщиком услуг, чтобы добавить новый белый список IP-адресов.
  • Существует множество способов настройки белого списка IP-адресов. В дополнение к традиционным брандмауэрам компонент Sentinel, предоставляемый Spring Cloud Alibaba, также поддерживает настройки белого списка.
  • Чтобы уменьшить сложность API, рекомендуется использовать правила брандмауэра для настроек белого списка.
3. Ограничение тока одного интерфейса для IP

Ограничение тока предназначено для лучшего поддержания стабильности системы.

Используйте Redis для подсчета количества вызовов интерфейса. IP+адрес интерфейса используется в качестве ключа, количество посещений используется в качестве значения, значение+1 запрашивается для каждого раза, а время истечения срока действия устанавливается для ограничения частоты вызовов интерфейса. .

4. Запись журналов запросов интерфейса.

Записывайте журналы запросов, быстро находите места ненормальных запросов и устраняйте причину проблемы. (Например: используйте aop для глобальной обработки запросов интерфейса)

5. Десенсибилизация конфиденциальных данных

В процессе вызова интерфейса могут быть задействованы конфиденциальные данные, такие как номера заказов. Этот тип данных обычно требует снижения чувствительности.

Наиболее часто используемый метод — шифрование. В методе шифрования используется асимметричное шифрование RSA с относительно высокой степенью безопасности. Существует два асимметричных алгоритма шифрования.ключ,Эти два ключа совершенно разные, но идеально совпадают. Используйте только совпадающую пару открытого и закрытого ключей.,Только после этого процесс шифрования и дешифрования открытого текста может быть завершен.

6. Проблема идемпотентности

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

  • Грубо говоря, операция запроса не повлияет на сами данные, независимо от того, сколько раз они запрашиваются, поэтому сама операция запроса идемпотентна.
  • но Новая операция,База данных будет меняться каждый раз при ее выполнении.,Следовательно, он неидемпотентен.

Существует много способов решения идемпотентных задач, и вот более строгий.

  • Предоставляет интерфейс для генерации случайных чисел, которые являются глобально уникальными. Введите случайное число при вызове интерфейса.
  • При первом вызове, после успешной бизнес-обработки, случайное число используется в качестве ключа, результат операции используется в качестве значения и сохраняется в redis, и одновременно устанавливается время истечения срока действия.
  • Второй вызов — запрос redis. Если ключ существует, это подтверждается повторной отправкой и напрямую возвращается ошибка.
7. Контроль версий

После публикации зрелого документа API интерфейс нельзя изменять по своему желанию. В настоящее время, если вы хотите добавить или изменить интерфейс, вам необходимо добавить контроль версий. Номер версии может быть целочисленным типом или типом с плавающей запятой.

Обычно адрес интерфейса имеет номер версии.,http://ip:port//v1/list , http://ip:port//v2/list

8. Спецификации кодов состояния ответа

Хороший API также должен предоставлять простые и понятные значения ответа. На основании кода состояния вы можете приблизительно определить проблему. Мы используем коды состояния HTTP для инкапсуляции данных. Например, 200 указывает на успешный запрос, 4xx указывает на ошибку клиента, а 5xx указывает на внутреннюю ошибку сервера.

Ссылка на дизайн кода состояния выглядит следующим образом:

Язык кода:javascript
копировать
public enum CodeEnum {// Добавьте в соответствии с потребностями бизнеса
    SUCCESS(200, «Обработано успешно»),ERROR_PATH(404, «Ошибка запроса адреса»),
    ERROR_SERVER(505, «На сервере произошла внутренняя ошибка»);

    private int code;
    private String message;

    CodeEnum(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
9. Унифицировать формат данных ответа

Для облегчения ответа клиенту,Данные ответа будут содержать три атрибута,Код состояния (код),Описание информации (сообщение),Данные ответа (данные)。Клиент может быстро узнать интерфейс на основе кода состояния и описания информации.,Если код состояния возвращает успех,Начните обработку данных снова.

Язык кода:javascript
копировать
public class Result implements Serializable {
    private static final long serialVersionUID = 793034041048451317L;
    private int code;
    private String message;
    private Object data = null;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    /** * Вставьте в ответ перечисление */
    public Result fillCode(CodeEnum codeEnum) {
        this.setCode(codeEnum.getCode());
        this.setMessage(codeEnum.getMessage());

        return this;
    }

    /** * Введите код ответа и информацию */
    public Result fillCode(int code, String message) {
        this.setCode(code);
        this.setMessage(message);

        return this;
    }

    /** * Обработано успешно, отправлено в специальный сбор бизнес-данных. */
    public Result fillData(Object data) {
        this.setCode(CodeEnum.SUCCESS.getCode());
        this.setMessage(CodeEnum.SUCCESS.getMessage());
        this.data = data;

        return this;
    }
}
10.Документация интерфейса

Хороший API также требует отличного интерфейса. Читабельность документации по интерфейсу очень важна, хотя многие программисты не любят писать документацию, и им не нравится, когда другие не пишут документацию. Чтобы не увеличивать нагрузку на программистов, рекомендуется использовать swagger2 или другие инструменты управления интерфейсом. Благодаря простой настройке возможность подключения интерфейса можно проверить во время разработки. После выхода в Интернет также можно создавать автономные документы для управления API. .

11. Подробные шаги по созданию подписи

В сочетании с делом подробно объясните, как сгенерировать Подпись (инсайты, полученные после написания вышеуказанного блога)

Шаг 1. Отсортируйте все параметры (обратите внимание на все параметры, включая appId, timeStamp, nonce), кроме самого знака и параметров с пустыми значениями, в порядке возрастания по имени ключа и сохраните их.

Шаг 2. Затем объедините отсортированные параметры в строку в соответствии с ключом1значение1ключ2значение2...ключXзначениеX.

Значение параметра и здесь должно быть исходным значением параметра передачи.,Его невозможно обработать,Если не получается "конвертировать" а потом склеить)

Шаг 3. Вставьте секретный ключ, назначенный вызывающему абоненту, в конец строки, полученной на шаге 2.

Прямо сейчас: ключ1значение1ключ2значение2…ключXзначениеX + секрет

Шаг 4. Вычислите значение md5 (32 бита) строки на шаге 3, затем преобразуйте его в верхний регистр, и окончательная строка будет Подпись.

То есть: Md5(key1value1key2value2…keyXvalueX + secret) Преобразовать в верхний регистр.

Пример:

Предположим, что передаваемые данные

http://www.xxx.com/openApi?sign=sign_value&k1=v1&k2=v2&method=cancel&k3=&kX=vX

Заголовок запроса

appId:zs001timeStamp:1612691221000sign:2B42AAED20E4B2D5BA389F7C344FE91Bnonce:1234567890

В реальных ситуациях лучше всего отправить его по почте.,вsignпараметры, соответствующиеsign_valueЭто значение подписи。

Шаг первый: объединить строки.

Сначала удалите сам параметр знака,Затем удалите параметр k3, значение которого пусто.,оставатьсяappId=zs001&timeStamp=1612691221000&nonce=1234567890&k1=v1&k2=v2&&method=cancel&kX=vX,Затем отсортируйте символы имени параметра в порядке возрастания.,appId=zs001&k1=v1&k2=v2&kX=vX&method=cancel&nonce=1234567890&timeStamp=1612691221000

Шаг 2. Имена и значения параметров соединения

appIdzs001k1v1k2v2kXvXmethodcancelnonce1234567890timeStamp1612691221000

Шаг 3. Добавьте секретный ключ перед строкой, соединенной выше.

Предположим, это Мияо,получить новую строкуappIdzs001k1v1k2v2kXvXmethodcancelnonce1234567890timeStamp1612691221000miyao

Шаг 4. Затем выполните расчет md5 для этой строки.

Предположим, что вы получаете abcdef,затем преобразовать в верхний регистр,получатьABCDEFЭто значение как Подпись

Обратите внимание, что перед вычислением md5 вызывающей стороне необходимо убедиться, что кодировка строки шифрования подписи соответствует поставщику, например, с использованием кодировки UTF-8 или кодировки GBK. Если метод кодирования несовместим, вычисленная подпись не сможет быть проверена.

Упомянутая выше запись запроса может быть склеена или нет, в основном для повышения сложности подписи.

12.1.Что такое токен?

Что такое токен?

токен немедленно доступ по токену доступа Токен используется в интерфейсе для идентификации личности и учетных данных вызывающего интерфейса, а также для уменьшения количества передач имени пользователя и пароля.  Обычно клиент (вызывающая интерфейс) сначала должен подать заявку на сервер для получения учетной записи для вызова интерфейса.,Сервер предоставит appId и appSecret (appSecret используется для подписи параметров).

Обратите внимание, что appSecret сохраняется на клиенте и требует некоторой обработки безопасности для предотвращения утечки.

Значение токена обычно равно UUID.,После того как сервер сгенерирует токен, ему необходимо использовать его в качестве ключа.,Сохраните некоторую информацию, связанную с токеном, как значение на кэш-сервере (redis).,Когда приходит запрос,Сервер обращается к серверу кэша, чтобы узнать, существует ли токен.,Если существует, вызовите интерфейс,Нет ошибки обратного интерфейса,Обычно реализуется через перехватчики или фильтры.

Токен делится на два типа

  • API Токен (токен интерфейса):  Используется для доступа к интерфейсам, не требующим входа пользователя.,Такие как вход в систему, регистрация, получение некоторых базовых данных и т. д. Чтобы получить токен интерфейса, вам необходимо обменять его на appId и timestampиsign.,знак=шифрование(параметр 1+…+параметр n+метка времени+ключ)
  • USER Токен (токен пользователя):  Используется для доступа к интерфейсам, требующим входа пользователя в систему.,нравиться:получать我из基本信息、держать、Исправлять、Удаление и другие операции. Чтобы получить пользовательский токен, вам необходимо обменять его на свое имя пользователя и пароль.

12.2.Токен+подпись (подпись интерфейса со статусом пользователя)

Все упомянутые выше методы подписи интерфейса не сохраняют состояние.,В дизайне открытого API-интерфейса приложения,Большинство интерфейсов потому что включают личную информацию пользователей и конфиденциальные данные продуктов.,Итак, аутентифицируйте эти интерфейсы,По соображениям безопасности, чем меньше раз открытый текстовый пароль должен быть доступен пользователям, тем лучше.,Однако взаимодействие клиент-сервер между запросами не сохраняет состояние.,То есть,Когда дело доходит до статуса пользователя,Каждый запрос должен принести аутентификационную информацию (токен).

1. Аутентификация токена

  • Вход пользователя предоставляет информацию для аутентификации (например, номер учетной записи и пароль) на сервер.,После успешной проверки сервер возвращает токен клиенту;
  • Клиент кэширует токен локально и переносит его с каждым последующим запросом;
  • Сервер проверяет действительность токена. Если он действителен, он будет выпущен, если он недействителен (токен неверен или срок его действия истек), он будет отклонен.

Недостатки: токен захватывается, подделываются запросы и подделываются параметры.

2. Проверка токена+подписи

Взаимодействие с вышеуказанными Правилами То же, что и оплата,Назначьте appSecret (ключ,Используется для шифрования интерфейса,в передаче не участвует),ВоляappSecretивсе Параметры запрос объединен в строку,Генерация значения подписи на основе алгоритма подписи,Отправить запросчас Воля Подписанное значение отправляется на сервер для проверки.。

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

Запрос на вход и выход

картина
картина

Последующие запросы

Клиент: Взаимодействие с вышеуказанными Правилами Доставка аналогична, измените appId на токен немедленно Может。

картина
картина

Последнее, что нужно сказать (обратите внимание! Не занимайтесь блудством просто так!)

Если эта статья оказалась для вас полезной или вдохновляющей, нажмите три раза: «Мне нравится», «Переслать» и «Читать».

сосредоточиться на Официальный аккаунт:woniuxgg,Ответ в паблике: Примечания  Вы можете получить практические заметки по Java, тщательно подготовленные для вас компанией Snail, ответить на интервью, получить руководства по разработке и получить потрясающие преимущества для поклонников!

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose