Дано:
Клиент - человек у которого есть сайт, на котором он хочет открывать мое приложение по расчету данных.
API сервер - мой сервер на Laravel.
База пользователей находится у клиента. Используя мое приложение - каждый пользователь его сайта может рассчитать данные. Эти данные хранятся в базе на сайте клиента.
API сервер ничего не знает о пользователях. Любой пользователь зайдя в приложение на сайте клиента - должен передать логин и исходя из логина будет запрос с API сервера на сервер клиенту, чтобы получить набор данных пользователя, чтобы это все подгрузилось в приложение.
Если передавать это через GET в строке src iframe, то можно через инструменты разработчика подменить логин и набор данных будет загружен для другого пользователя.
Как этого избежать. Пока идея иметь API ключ на API сервере и на сервере клиента, и шифровать и расшифровывать используя этот ключ логин в GET параметре.
И еще интересует момент, можно ли подменить данные в curl запросе с API сервера на сервер клиента. Или можно доверять этим данным?
И можно ли, используя что либо из массива $_SERVER, запретить доступ к API если он произведен не с определенного домена, а допустим с локального сервера пользователя. Хотя я думаю что можно сделать локальный домен, и тогда это не защитит. Только привязка к IP сервера клиента?
Тут в рамках защиты от подделки запроса разве что токен с клиента и обратный запрос к сервера к клиенту на подтверждение, что это он вошел с таким токеном.
я них... чего не понял.
что это за чушь - "база пользователей на клиенте"? Это в том самом ифрейме у нас база пользователей болтается?
если у вас, как почему-то принято у фронтендеров, сервер почему-то делится на две части, "клиент-сервер" и "сервер-сервер", то о какой части взаимодействия идет речь? клиент-браузер -- клиент-сервер или клиент-сервер -- сервер-сервер?
В обоих случаях проблемы с защитой я никакой не вижу вообще
FanatPHP, я так понял, это что-то вроде системы, в которой у каждой поликлиники свой сервер, но они на один общедоступный сайт валят расписание и запись к врачам. Прямо через открытый у оператора браузер. А на общедоступном сервере - голое API без всяких учеток (почему-то).
Adamos, ну то есть это взаимодействие сервер-сервер?
или приложуха в браузере работает одновременно как с локальным "сервером", так сама через голову "сервера" общается ещё и с глобальным "АПИ"?
FanatPHP, судя по бардаку в вопросе - и то, и другое %)
А если я прав насчет схемы работы, то еще и третье: сервер-сервер в обратную сторону (записи внешних пользователей - во внутреннюю систему).
Внесу ясность. Есть сайт который берет у меня приложение по API. База пользователей находится у них. Мне копировать базу к себе нет смысла. Просто используя мое приложение меняются данные в их базе у их пользователей. У меня есть только сервер и админ панель. У клиента есть фронтенд и бэкенд. Вот во фронтенде открывается фрейм, в котором грузится приложение. Используя алгоритмы на моем сервере, происходит изменение данных. Эти данные должны меняться у пользователей на стороннем сайте.
P.S. Я понимаю что это не массив а строка. Я имел ввиду массив $_SERVER. Просто дописал какой конкретно элемент массива я использую для проверки что запрос пришел именно с разрешенного домена.
Клиент - (человек) сайт который взял мое API. Они грузят приложение во фрейме и приложение меняет данные в их системе.
API сервер - я, просто Laravel, фронт - это админка. Нет ничего больше кроме запросов и ответов.
Клиент открывает во фрейме приложение. Там есть поля, он может изменить какие то из них - и в базе на клиенте изменятся данные этого пользователя. Этими данными он может пользоваться на этом же сайте в других разделах.
Моя задача как API просто рассчитать эти данные и вернуть. Как они будут их использовать это уже не мое дело.
Но я должен знать что я рассчитываю данные конкретно под того пользователя который открыл приложение. То есть передать в GET параметре его логин. Чтобы после расчета послать на клиент данные привязанные к этому логину, на бэкенд клиента (человека).
Если я в браузере изменю параметр GET - то расчет будет произведен для другого пользователя. Вот я и думаю как это предотвратить. Иметь а бэкенде клиента АПИ-ключ и на своем сервере, и использовать его чтобы шифровать GET параметры и расшифровывать. Правильно ли это?
И можно ли подменить что то, если я со своего бэкенда, через CURL отправляю на бэкенд клиента(человека) информацию. Или чтобы что то подменить обязательно нужно чтобы было общение через браузер?
FanatPHP, Потому что человек должен открыть iframe. Это не сервер. Это браузер. Как понять какой именно пользователь открыл iframe чтобы подгрузить его данные через запрос к серверу клиента(человека)?
FanatPHP, с моим сервером и так будет общаться бэкенд клиента. Но мне нужен первый запуск. Инициализация приложения. Чтобы оно запустилось - нужно получить логин пользователя который его запустил. я вижу это только через GET параметр. В iframe грузится blade шаблон который запускает приложение.
Если только один запуск то вообще без проблем. клиентское приложение генерит токен, подписывает его хэшем, отправляет токен в апи, а хэш в ифрейм. ифрейм отправляет хэш в апи, который проверяет его валидность
FanatPHP, То есть по сути можно сделать так же используя API ключ!? На API сервере сопоставить API ключ определенному домену или IP. И этот ключ есть у клиента, и параметры GET будут зашифрованы этим ключом. На сервере пришедшие параметры будут расшифрованы используя тот же ключ API. Использовать openssl_encrypt и openssl_decrypt наверное!? Или есть что то попроще может. А общение сервера с бэкендом клиента никак не подменить ведь? Это просто моя параноя?)
да при чем здесь вообще айпи или домен? что это вообще за бред - "сопоставить API ключ"? API ключ И ЯВЛЯЕТСЯ идентификатором легального клиента! Зачем тут какой-то ещё ip?
И что такое "общение сервера с бэкендом клиента подменить"? ЧТО конкретно подменить? АПИ ключ? Ну так зависит от того какой ключ. Если 12345, то легко
FanatPHP, IP затем чтобы нельзя было запустить приложение с другого сервера, даже зная ключ. Хотя конечно если знать ключ то можно натворить других дел.
Подменить данные. То есть если я с API сервера отправил (user: test, data: datasheet) То можно ли как то сделать чтобы на сервер клиента пришло (user: admin, data: delete_all) ? Или я параною?
FanatPHP, API сервер имеет общение с бэкендом клиента. Он отправляет туда измененные данные. которые изменяются благодаря действиям пользователя в приложении. Я не могу напрямую у клиента изменять данные через приложение. Или могу?
FanatPHP, О боже. Что сложного? Приложение находится на моем сервере. Логика на моем сервере. Клиент открывает приложение, и что то там делает. Приложение открывается через iframe, и использует логику на моем сервере. Когда данные изменились - как изменить их в базе у клиента? Только отправив запрос через CURL с моего сервера на бэкенд клиента. Он получает эти данные и записывает себе в базу. По моему тяжелые наркотики принимаете вы. Это не простая API пересылающая массивы json. Логика приложения находится на сервере. Как только логика сделала расчет - она отправляет это на эндпоинт у клиента, он пишет себе в базу изменения которые пользователь произвел в моем приложении.
FanatPHP, Я уже писал что клиент - это человек, который берет у меня API. Я не имею доступа ни к его коду ни к его базе ни к бэкенду. Я шлю ему данные после расчетов в приложении, которое работает на его сайте через iframe. И у него нет доступа к моему коду.
Тогда не надо называть это API.
Потому что к защите API вопрос "можно ли как то сделать чтобы на сервер клиента пришло (user: admin, data: delete_all)" никакого отношения не имеет.
Вячеслав Правильный, так вы что защищаете-то? Запрос к вашему API (считать только тому, кто подтвердил, что это он) или валидность того, что оно отдает (заносить только то, что было рассчитано для этого сервера)?
Adamos, То что отдает, нужно ли это защищать? Или тут и так все происходит на бэкендах и никто не имеет доступа к этому если только не получил доступ к серверу.
Запрос к моему серверу при первом запуске я уже примерно понял как защитить. API key и шифрование openssl и расшифровка на моем сервере. Не имея ключ нельзя подменить логин на другого пользователя в GET параметре.
Осталось только отрезать запросы со сторонних ресурсов. HTTP_REFERER я уже почитал что можно подменить. Как разрешить вызовы только с определенного домена пока не знаю. Можно ведь сделать локальным домен.
Я так понял что если ключ будет другим - то расшифровки не произойдет, пробовал сейчас в коде изменять ключ, не идет расшифровка. Я думал что с другим ключом он просто расшифрует как набор символов. Походу все вопросы допер. В споре рождается истина)
FanatPHP, Я думаю да, можно такое сравнение провести. Подписывать ответ, вы имеете ввиду хэшем? Колбек для того, чтобы после записи изменений у клиента - мне пришел ответ что у клиента все изменено успешно?
FanatPHP, Это есть. Но я думал что он может быть постоянным, я не понимаю сейчас что значит "регистрировать". Либо я понял это не так, что при каждом запросе передавать колбэк.
Он будет прописан у меня в коде, его предоставит сам клиент.
чтобы он был постоянным, ваш "апи сервер" должен его знать. то есть при подключении к системе клиент должен сообщить серверу адрес. и этот адрес сервер должен у себя записать
прочитав этот бред, я так и не понял, человек запуская свое приложение (свой сайт, со своего бэка), видит во фрэйме кусок приложения загруженного с твоего бэка? а потом, когда пользователь что-то сделал во фрэйме, данные с фрэйма идут на твой бэк, а он в свою очередь пересылает их на бэк пользователя?
Как этого избежать. Пока идея иметь API ключ на API сервере и на сервере клиента, и шифровать и расшифровывать используя этот ключ логин в GET параметре
ага, токен для каждого юзера иметь и принимать данные если клиент его предъявил