Возможное дублирование:
написание веб-приложений «без сервера»
Итак, допустим, я собираюсь создать клон Stack Exchange и решил использовать что-то вроде CouchDB в качестве своего внутреннего хранилища. Если я использую их встроенную аутентификацию и авторизацию на уровне базы данных, есть ли какая-либо причина не разрешать клиентскому Javascript писать напрямую на общедоступный сервер CouchDB? Так как это в основном приложение CRUD, а бизнес-логика состоит из «Только автор может редактировать свою публикацию», я не вижу особой необходимости иметь слой между клиентской частью и базой данных. Я бы просто использовал проверку на стороне CouchDB, чтобы удостовериться, что кто-то не вставляет мусорные данные, и убедиться, что разрешения установлены правильно, так что пользователи могут только читать свои собственные данные _user. Рендеринг будет выполняться на стороне клиента чем-то вроде AngularJS. По сути, вы могли бы просто иметь сервер CouchDB и кучу «статических» страниц, и все готово. Вам не понадобится какая-либо обработка на стороне сервера, только то, что может обслуживать HTML-страницы.
Открытие моей базы данных для всего мира кажется неправильным, но в этом сценарии я не могу понять, почему, если разрешения установлены правильно. Это противоречит моему инстинкту веб-разработчика, но я не могу придумать вескую причину. Итак, почему это плохая идея?
РЕДАКТИРОВАТЬ: Похоже, что есть подобное обсуждение здесь: написание веб-приложений "без сервера"
РЕДАКТИРОВАТЬ: Потрясающее обсуждение до сих пор, и я ценю все отзывы! Я чувствую, что должен добавить несколько общих предположений вместо того, чтобы специально вызывать CouchDB и AngularJS. Итак, давайте предположим, что:
- База данных может аутентифицировать пользователей прямо из своего скрытого хранилища
- Вся связь с базой данных будет происходить через SSL
- Проверка данных может (но, возможно, не должна?) Обрабатываться базой данных.
- Единственная авторизация, о которой мы заботимся, кроме функций администратора, это то, что кому-то разрешено редактировать только свой пост.
- Мы прекрасно понимаем, что каждый может прочитать все данные (КРОМЕ пользовательских записей, которые могут содержать хэши паролей)
- Административные функции будут ограничены авторизацией базы данных
- Никто не может добавить себя в роль администратора
- База данных относительно легко масштабируется
- Практической бизнес-логики практически нет; это базовое приложение CRUD
источник
DELETE FROM ImportantData;
Ответы:
Выполнение, как вы предлагаете, создает тесную связь между вашим клиентским языком и вашей базой данных.
Это может быть хорошо - меньше кода для написания и поддержки, и в теории отладка может / должна идти немного быстрее.
С другой стороны, это усложняет другие аспекты. Если / когда вам нужно изменить одну из этих технологий, вам будет сложнее из-за тесной связи между ними.
Защитить себя от атак будет (довольно) немного сложнее. Вы предполагаете, что клиент всегда будет представлять красиво отформатированные запросы к базе данных. Это предполагает, что никто никогда не взломает код на стороне клиента для вставки вредоносных утверждений. Другими словами, они «заимствуют» ваши механизмы аутентификации и заменяют обычный клиентский код их.
Я не рекомендовал бы это, и многие яростно сказали бы Вам не делать этого. Но это можно сделать.
источник
Это, вероятно, не очень хорошая идея. И первая и самая веская причина, которую я могу привести, заключается в том, что сервер баз данных не предназначен для использования в качестве публичного веб-сервера. Наоборот, общепринятая мудрость гласит, что вы должны скрывать свою базу данных за брандмауэром.
Если вам нужны подтверждающие доказательства, есть много проблем - не все непреодолимые, но много о чем подумать. В произвольном порядке, вот несколько:
... И я уверен, что есть другие проблемы. И я уверен, что есть решение для большинства - если не для всех этих проблем. Но есть список, с чего можно начать!
источник
Лучшая единственная причина, которую я могу себе представить, заключается в следующем: потому что этот метод не поддерживается напрямую или не рекомендуется какой-либо вовлеченной стороной.
Поставщики браузеров, стандарты EcmaScript, разработчики систем баз данных, компании, занимающиеся сетевым оборудованием, архитекторы хостинга / инфраструктуры и специалисты по безопасности не активно поддерживают (или, возможно, даже не учитывают) предложенный вами вариант использования. Это проблема, потому что ваш предложенный метод требует, чтобы все эти объекты - и даже больше - работали надлежащим образом для вашего приложения, даже если ни одна из задействованных систем не была разработана для поддержки этого.
Я не говорю, что это невозможно. Я просто говорю, что это не похоже на «заново изобретать колесо», а скорее на изобретение взаимодействия между клиентом и сервером на основе браузера.
В лучшем случае вы будете выполнять массу работы, чтобы заставить системы работать на самом базовом уровне. Современные популярные базы данных не являются RESTful и не созданы для работы по HTTP, поэтому вы будете создавать свои собственные клиентские драйверы на основе WebSocket (я полагаю).
Даже если вы получите все для технической работы, вы потеряете многие из самых мощных функций современных архитектур. У вас не будет никакой глубокой защиты - каждый может легко подключиться непосредственно к основной цели большинства попыток взлома сайта. Но сценарий, который вы предлагаете, намного, намного хуже, чем этот.
Предложенная модель не просто представляет сервер - она предоставляет действительные строки подключения. Злоумышленники не могут просто пропинговать сервер - они могут активно входить в систему и кормить его командами. Даже если вы можете ограничить доступ к данным, я не знаю достаточного инструментария в системах СУБД для защиты от сценариев отказа в обслуживании и подобных им. При работе в усовершенствованных версиях SQL, таких как TSQL, зачастую легко создавать бомбы, которые работают эффективно бесконечно (несколько неограниченных объединений для создания декартового продукта, и вы получите SELECT, который будет работать вечно, выполняя тяжелую работу) , Я полагаю, вам нужно отключить большинство функций SQL, даже исключив базовые запросы SELECT с помощью JOIN и, возможно, разрешить только вызов хранимых процедур? Я даже не знаю, сможете ли вы это сделать, меня никогда не просили попробовать. Это не
Масштабируемость базы данных также является одной из самых сложных проблем при работе в больших масштабах, в то время как масштабирование нескольких HTTP-серверов - особенно со статическими или кэшированными страницами - является одной из самых простых частей. Ваше предложение заставляет базу данных выполнять больше работы, поскольку она отвечает за 100% активности на стороне сервера. Это убийственный недостаток сам по себе. То, что вы получаете от переноса работы на клиента, вы теряете, перенося больше работы на базу данных.
Наконец, я просто хотел бы отметить, что суть того, что вы предлагаете, не нова, а на самом деле насчитывает десятилетия. Эта модель называется моделью «толстой базы данных», которая в основном перемещает большую часть серверной логики в базу данных, как вы предлагаете. Есть много причин, по которым эта модель ушла на второй план в массовом интернете, и, вероятно, было бы полезно узнать больше об этой истории. Также обратите внимание, что даже тогда было мало смысла в том, чтобы иметь абсолютно ненадежных пользователей, способных войти в систему и выполнить команды, поскольку доступ по-прежнему будет контролироваться для выбора внутренних (известных) пользователей, которые не должны постоянно атаковать систему.
Дело в том, что вам все еще понадобится HTTP-сервер для обслуживания файлов, поскольку системы баз данных просто не делают этого. В то же время все, что вы предлагаете, может быть получено с помощью модели тонкого сервера (например, с Nodejs) для предоставления интерфейса RESTful к вашей базе данных. Это популярно по определенной причине - оно работает, сохраняет базу данных скрытой за уровнями защиты, чрезвычайно масштабируемо, и в то же время позволяет вам строить вашу базу данных настолько толстой или тонкой, насколько вам нужно.
источник
Хорошо, размещение вашей авторизации (проблемы безопасности) и логической проверки вне базы данных обеспечивает разделение проблем в вашей программной системе. Таким образом, вы можете тестировать, поддерживать, масштабировать и повторно использовать блоки логического кода с меньшими рисками нарушения работы системы.
Предоставление возможности клиентского ввода напрямую общаться с базой данных имеет очень большой потенциал, чтобы испортить данные .
Это также означает, что устранение / устранение жесткой связи делает вашу программную систему более удобной и надежной.
источник
Разрешение пользователю взаимодействовать с базой данных напрямую мне кажется очень опасным.
Является ли механизм аутентификации CouchDB настолько сложным, что вы можете изолировать доступ пользователя для чтения и записи только к тем данным, которые он должен прочитать и записать (мы говорим о доступе к документу, возможно, даже к доступу к полю документа) привилегии здесь)? А как насчет «общих» данных, которыми пользуются несколько пользователей? Разве это не существует вообще в дизайне вашего приложения?
Вы действительно хотите, чтобы пользователь мог изменять свои данные любым способом? Как насчет инъекций XSS, например? Не лучше ли иметь серверный уровень, чтобы фильтровать их, прежде чем они попадут в базу данных?
источник
У вас есть несколько причин, но вот еще одна: будущее. Рано или поздно, по мере развития вашего приложения, вы будете сталкиваться с некоторыми требованиями, которые не могут быть легко или безопасно выполнены в JS на стороне клиента или в качестве хранимой процедуры в вашей базе данных.
Например, вам говорят, что для всех новых регистраций необходимо иметь подтверждение CAPTCHA, чтобы быть действительным. Это было бы достаточно просто с любой современной платформой веб-приложений. Просто добавьте reCAPTCHA в регистрационную форму, передайте токен ответа reCAPTCHA обратно в бэкэнд и добавьте пару строк кода в свой бэкэнд, чтобы проверить действительность токена с помощью API Google (или еще лучше, используйте для этого библиотеку, написанную кем-то другим). для тебя).
Если вы используете двухуровневую систему и полагаетесь на базу данных для всей серверной логики, как вы собираетесь проверять токен? Да, я полагаю, что теоретически возможно в зависимости от СУБД написать хранимую процедуру, которая каким-то образом вызывает оболочку и вызывает curl с соответствующими аргументами. Это также почти наверняка ужасная идея: фильтрация входных данных и защита от уязвимостей безопасности были бы ужасны; у вас был бы беспорядок, связанный с обработкой ошибок и тайм-аутами; и вам придется проанализировать ответ самостоятельно. Не говоря уже о том, что СУБД не предназначена для этого, поэтому нет оснований считать, что производительность, стабильность, безопасность потоков и т. Д. Не будут иметь проблем. Смотрите, например, эту ветку , в которой обсуждаются некоторые из этих проблем для Postgres.
И это только проблемы, связанные с добавлением одной простой капчи в форму. Что вы собираетесь делать, если вы хотите добавить подтверждение по SMS или фоновое задание, которое отправляет по электронной почте неактивным пользователям напоминание о вашем приложении или добавить функцию загрузки файлов, чтобы люди могли установить изображение профиля? Может быть, вы решили, что ваше приложение когда-нибудь должно пройти несколько автоматических тестов? Или что вы хотели бы отслеживать изменения в ваших процедурах в системе контроля версий? Существует множество библиотек и инструментов для большинства полезных языков, которые могут выполнять большинство этих задач для вас, но для вашей СУБД будет доступно очень мало, потому что это не предназначено для этого.
В конце концов, вам захочется сделать что-то, что вы не можете разумно сделать напрямую в вашей СУБД, и тогда вы застрянете. Поскольку вы построили все приложение в своей СУБД, у вас не будет другой альтернативы, кроме как получить веб-сервер и начать перестраивать компоненты на другом языке, просто добавив простую функцию.
И это было бы настоящим позором, потому что у нас уже есть название места, куда вы помещаете логику вашего приложения, и оно называется «исходный код вашего приложения», а не «хранимые процедуры базы данных» по причине.
источник
Если ваши проверки безопасности и бизнес-логика содержатся в вашем клиентском JavaScript, они могут быть переопределены злоумышленником. В качестве альтернативы вы можете использовать серверную технологию на основе JavaScript (например, Node.JS ) для обработки проверки, авторизации и тому подобного.
источник
Любое деловое ограничение, которое вы можете захотеть обеспечить, должно быть проверено на стороне сервера Даже если вы контролируете доступ пользователей, кто-то может отправлять неверные данные.
Следуя вашему примеру клона stackoverflow:
Любой может манипулировать кодом на стороне клиента и полностью нарушать целостность данных (даже если он ограничен определенными объектами, такими как их собственные сообщения).
источник
Отредактируйте страницу в firebug и в какой-то момент поместите строку, подобную этой:
ExecDbCommand("DROP TABLE Users")
Запустить его.
Редактировать:
Вопрос был на самом деле о CounchDB, так что нет sql для запуска здесь. Все же идея та же самая. Я бы предположил, что любое нетривиальное приложение зависит от данных для соблюдения некоторых правил согласованности, которые проверяются / применяются кодом приложения. Злонамеренный пользователь может изменить код клиента, чтобы сохранить данные в форме, которая нарушает ваши бизнес-правила и может вызвать хаос в вашем приложении.
Если ваш сайт считает, что все возможные состояния данных являются действительными с точки зрения бизнеса, то во что бы то ни стало идите по этому пути, но если это не так (вероятно), то вы хотели бы иметь гарантию, что любые данные, которые хранятся, генерируются вашим код и в соответствии с вашими правилами .
источник
Старый вопрос, я знаю, но я хотел вмешаться, потому что мой опыт сильно отличается от других ответов.
Я потратил много лет на написание приложений для совместной работы в реальном времени. Общий подход к этим приложениям заключается в локальной репликации данных и максимально быстрой синхронизации изменений с одноранговыми узлами. Все операции с данными являются локальными, поэтому все хранилище данных, доступ к данным, бизнес-логика и пользовательский интерфейс являются локальными уровнями. Движение "оффлайн сначала" ( http://offlinefirst.org/ ) приняло этот подход для создания автономных веб-приложений и может иметь некоторые соответствующие ресурсы. Подобные сценарии использования требуют не только открытия слоя доступа к данным для клиентов, но и хранения данных! Я знаю я знаю. Кажется сумасшедшим, верно?
Проблемы с такими офлайновыми первыми приложениями аналогичны тем, что вы просили, только один уровень удален. Это кажется мне актуальным. Учитывая, что вы открываете прямой доступ к данным для клиентов, возникает вопрос, как вы можете ограничить влияние злоумышленника? Ну, есть много стратегий, но они неочевидны, если вы пришли из более традиционной среды разработки.
Первое заблуждение состоит в том, что разоблачение базы данных означает раскрытие всех данных. Взять, к примеру, CouchDB; базы данных в CouchDB легки, поэтому у вас не возникнет и мысли о создании сотен тысяч отдельных баз данных на сервере. Пользователи могут получить доступ только к базам данных, доступ к которым им предоставлен как читатель или писатель (не говоря уже о функциях проверки и прочее CouchDB), поэтому они могут получить доступ только к подмножеству данных.
Второе заблуждение состоит в том, что пользователь пытается получить доступ к данным. Если пользователям дается копия базы данных, они могут копировать все, что им нравится, не затрагивая других пользователей. Но вы должны проверить их изменения, прежде чем реплицировать их данные обратно в «центральное» хранилище. Подумайте о Git - пользователи могут делать все, что им нравится в ветках, вилках и локальных репозиториях, не затрагивая основную ветку. Слияние с мастером требует много церемоний и не делается вслепую.
В настоящее время я создаю систему с использованием CouchDB, где пользователям необходимо совместно работать с данными, чтобы создать набор данных, который затем «публикуется» с помощью рабочего процесса QA / QC. Сотрудничество осуществляется на реплике данных (мы называем это промежуточной или рабочей базой данных), и после ее завершения ответственный сотрудник выполняет QA / QC для данных, и только после этого они реплицируются обратно в главный репозиторий.
Из этого вытекают многие преимущества, которые трудно достичь в других системах, такие как управление версиями, репликация и совместная работа (не говоря уже о работе в автономном режиме!) Для традиционных трехуровневых приложений CRUD.
Мой совет - если ваше приложение «традиционное», делайте это традиционным способом. Если что-то из того, что я упомянул выше (хотя есть намного больше ...), применимо к вам, тогда подумайте об альтернативных архитектурах и будьте готовы мыслить со стороны.
источник
Я думаю, что, учитывая все ваши предположения, возможно перейти непосредственно от клиента к базе данных. Тем не менее, разумно посмотреть, верны ли ваши предположения и, вероятно, останутся таковыми в будущем.
Я был бы обеспокоен тем, что в будущем не все смогут читать все данные, и в особенности это может привести к развитию бизнес-логики в будущем. Оба из них более вероятны, если проект успешен.
Пока вы оставляете себе способ справиться с этими проблемами в будущем, когда и если вам действительно нужно с ними бороться, я думаю, ваш дизайн будет работать. Я думаю, вам нужно быть очень осторожным, чтобы разделить проблемы в коде JavaScript, и некоторые из них могут в конечном итоге быть переписаны на сервере позже.
Но я определенно мог видеть, где это может стоить риска, возможно, сделать это позже, в сравнении с преимуществом меньшего количества движущихся частей сегодня.
источник
Прежде всего, спасибо за вопрос OUT OF THE BOX .... :)
Но то, что я хотел бы предложить, это; Всегда старайтесь поддерживать разделение между вашими 3 слоями. это Презентация / Бизнес и База данных или DAO, потому что это будет наилучшей практикой в тех видах требований и настройках, где каждый день будет происходить множество изменений.
В простых мирах ваш уровень презентации не должен знать о уровне базы данных, т. Е. Формат некоторых полей типа даты может отличаться от уровня представления и уровня базы данных, поэтому пользователь может свободно выбирать подходящий формат даты в соответствии со своими потребностями.
А бизнес-логика должна действовать как связующее звено между уровнем представления и уровнем базы данных / дао, таким как приведение полей, некоторые проверки бизнеса и т. Д., Которые должны обрабатываться на бизнес-уровне, а не в разделе Javascript согласно вашему вопросу.
Эта сегрегация обеспечит вам большую простоту и удобство при сложных сценариях, функциональности и даже сложных проверках. Лучшее преимущество: у вас могут быть разные технологии для реализации этих уровней, и они могут быть изменены в соответствии с потребностями или областью бизнеса
Спасибо
источник
Если вы хотите встроить SQL в JavaScript и отправить его в базу данных, которая проверяет права и т. Д., То по соображениям безопасности это будет катастрофой. Просто потому, что когда вы создаете API и строите запросы самостоятельно, вам необходимо анализировать с точки зрения безопасности только ограниченное количество запросов. Если запросы строятся вне вашей системы, у вас есть потенциально неограниченное количество хитростей, которые кто-то может сделать.
Но это не так, поскольку вы используете базу данных ключ-значение (насколько я понимаю, CouchDB обычно попадает в эту категорию). Сам интерфейс базы данных является своего рода промежуточным уровнем, и он проверен по соображениям безопасности командой Apache. Из-за относительно простого JavaScript API это даже легче проанализировать на наличие потенциальных недостатков, чем такие сложные интерфейсы, которые есть у приложений JSF.
Это может быть безопасным решением, если вы проводите сложные тесты безопасности. Это может быть даже проще, чем при использовании таких фреймворков, как JSF, которые часто используют трудно читаемый API. Безопасность по неизвестности не считается решением.
Что касается вашего вопроса, это не будет прямой доступ к базе данных в любом случае. Прямой доступ был бы созданием SQL-запросов в JavaScript (к сожалению, я видел такие решения). В вашем случае CouchDB сам обеспечивает слой изоляции. Конечно, вы можете обернуть его в свой API, чтобы укрепить его, но если вы можете легко проверить, что может делать конкретный пользователь, и если ограничения безопасности работают на вас, у вас будет безопасное и надежное решение без дополнительных уровней.
источник
Я вижу две проблемы:
1. Плотная муфта: изменить вариант БД? Ну, теперь вы должны изменить весь свой клиентский код тоже. Доверьтесь мне. Нам не нужно больше проблем на стороне клиента.
2. Проблема безопасности TMI: слишком много рассказывает о том, как все работает. Проверка подлинности может все еще быть препятствием, но найти эксплойт будет намного проще, когда вы точно знаете, что происходит на стороне сервера.
Очень-очень тонкий средний уровень может быть лучшим способом.
источник
Ваш клиент не может использовать ваше веб-приложение, если javascript отключен (или не поддерживается в браузере его устройства), если javascript является единственным уровнем доступа к базе данных.
источник