Тему безопасности во фронтенд-части можно разделить на две цели:

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

Первая часть - это очень обширная тема, которая охватывает такие вещи, как межсайтовый скриптинг (XSS), межсайтовый запрос-подделка (CSRF), CORS и другие темы, связанные с тем, как браузер предотвращает утечку ваших данных злоумышленнику или предотвращает злоумышленник от выполнения действий от вашего имени.

Вторая часть больше связана с тем, «как мне ограничить доступ пользователей к определенным частям моего сайта» - таким вещам, как раздел только для участников, панель администратора и т. Д.

Безопасны ли переменные в браузере?

Ваша первая идея может быть такой: «Я собираюсь создать isAdmin переменную, установить ее в true каждый раз, когда администратор аутентифицируется, а затем проверю ее в моем приложении.

Но как только вы реализовали это решение - у вас возникает вопрос: «Что, если пользователь просто откроет инструменты разработчика и изменит его на true на своей стороне? Как я могу это предотвратить? Должен ли я использовать localStorage, sessionStorage или есть что-то более безопасное? »

Нам нужно прояснить одну вещь - все, что вы помещаете в клиентский браузер, может быть легко изменено клиентом. Браузер по умолчанию предоставляет злоумышленнику все необходимые инструменты. Он может открыть инструменты разработчика и изменить все переменные в памяти. Он может манипулировать localStorage, sessionStorage, cookies, а с правильными расширениями - даже состоянием компонентов React. Он также может заменить ответ auth endopint и просто каждый раз давать ответ с помощью {isAdmin: true}.

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

Как запретить пользователю доступ к закрытым частям моего сайта?

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

"Хорошо, это совсем небезопасно - каждый может перейти на страницу администратора и удалить все!" Вы кричите.

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

Это внутренняя задача для выполнения этой проверки!

В вашем интерфейсе может быть кнопка «Удалить базу данных». Вы можете даже попытаться скрыть это с помощью некоторой логики, но злоумышленник может загрузить код JavaScript и искать все конечные точки - он найдет http://example.com/api/database/delete URL (это только для примера, вы всегда должны использовать нотацию CRUD в любом случае :) ) и вызовите его вручную. Если эта операция завершается удалением вашей базы данных - вам серьезно нужно повысить безопасность вашего приложения.

Аналогичным образом ваше приложение может отображать только содержимое элементов под /members/blogpost/read-up-on-all-the-new-things - злоумышленник всегда может перейти к нему напрямую. Если он увидит контент, это означает, что ваш API (или другие формы доставки контента) спроектирован неправильно - злоумышленник должен быть немедленно перенаправлен на /sign-up, или в худшем случае он должен увидеть шаблон сообщения в блоге без каких-либо контент загружен.

Backend - решающий фактор

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

Если действие разрешено, выполните его и ответьте правильным кодом HTTP (например, 200), если это не разрешено, ответьте кодом ошибки HTTP, например 401 (не аутентифицирован) или 403 (не авторизован). Ваш интерфейс должен отреагировать на это и либо сообщить пользователю, что он делает что-то, на что у него нет разрешения (показать сообщение об ошибке, перенаправить на экран входа в систему), либо просто корректно завершиться неудачей (отобразить шаблон без содержимого или * ахнуть! * - Published at: <date>undefined</date> ).