Как защитить "публичную" часть службы REST от спама?
У меня есть служба REST, которая достаточно полная и будет использоваться с iOS-приложением. Он построен с использованием Ruby/Sinatra, но я не думаю, что это действительно важно.
Я использую HTTP Basic Authentication over SSL для различных конечных точек, и эта часть работает очень хорошо.
Вопрос:
Как остановить спамеры и т.д. От вызова частей службы REST, которые не защищены через HTTP Basic Authentication?
Пример: Регистрация пользователя
Предположим, что вызов REST (POST) .../register_account передаёт объект JSON в теле.
По понятным причинам этот вызов не может ожидать имя пользователя/пароль, связанные с учетной записью пользователя.
Идеи:
1) Приложение имеет свое "имя пользователя" /пароль, и некоторые вызовы будут проверять наличие учетных записей приложений.
Проблема. Коррекция устройства и т.д. Может выявить эти учетные данные.
2) Приложение передает секретный токен через HTTP-заголовок в службу REST для этих вызовов.
Проблема: То же, что (1)
Существуют ли какие-либо методы, обычно используемые для предотвращения подобных спам-звонков? Я думаю, может быть, представила идентификатор устройства iPhone в миксе, но пока не определил определенный подход.
Спасибо
Ответы
Ответ 1
В то время как код, специфичный для приложения, является хорошей идеей для первой линии защиты от спама, вы все равно должны использовать ограничение скорости для любых служб, о которых вы беспокоитесь.
Например, если вы используете сеансы в своих службах REST, вы можете легко ограничить количество вызовов, которые вы обрабатываете, с одного сеанса. Сеанс не обязательно должен быть аутентифицирован и используется только для идентификации одного клиента во время выполнения запросов. Простое перенаправление обратно на запрашиваемую службу, если они пытаются подключиться без открытого сеанса, - все, что нужно, и практически все веб-фреймворки или стеки имеют встроенную функцию.
Вы также можете ограничить скорость для других свойств, таких как IP-адрес или отпечаток пальца пользователя, но они менее надежны, чем метод на основе сеанса.
Ответ 2
В общем, общий подход - это API-ключ, который совпадает с секретным токеном, который вы описали выше. Вы можете жестко закодировать это в своем приложении и затруднить кому-то его перепроектировать (скрыть его, создать из разных частей, хранящихся в разных местах вашего приложения, и т.д.). Вы правы в том, что определенный злоумышленник сможет восстановить ключ (если ваше приложение может это сделать, кто-то еще с доступом к вашему приложению может также)... но вы можете усложнить ситуацию там, где, надеюсь, Не стоит тратить время и силы на это.
Вы также можете посмотреть развертывание SSL с использованием взаимной аутентификации, чтобы ваш сервер принимал только входящие соединения из вашего приложения, и ваше приложение будет взаимодействовать только с вашим сервером.
Вот высокоуровневый подход. Создайте сертификат SSL с самозаверяющим сервером и разверните его на своем веб-сервере. Затем создайте самозаверяющий клиент и разверните его в своем приложении в качестве ресурса. Настройте сервер, требующий аутентификации на стороне клиента, и только принять сертификат клиента, который вы создали. Настройте клиента для использования этого сертификата на стороне клиента для идентификации себя и принимайте только тот серверный сертификат, который вы установили на своем сервере для этой части.
Если кто-то, кроме вашего приложения, пытается подключиться к вашему серверу, соединение SSL не будет создано, так как сервер отклонит входящие SSL-соединения, которые не представляют сертификат клиента, который вы включили в ваше приложение.
Ответ 3
Вы можете отслеживать IP-адреса с помощью request.ip
и записывать некоторую логику вокруг этого.