Примечание. Следующая статья поможет вам: Как включить CORS с HTTPOnly Cookie для защиты токена?
В этой статье мы увидим, как включить CORS (обмен ресурсами между источниками) с файлом cookie HTTPOnly для защиты наших токенов доступа.
В настоящее время внутренние серверы и внешние клиенты развернуты в разных доменах. Поэтому сервер должен включить CORS, чтобы клиенты могли общаться с сервером в браузерах.
Кроме того, серверы реализуют аутентификацию без сохранения состояния для лучшей масштабируемости. Токены хранятся и поддерживаются на стороне клиента, а не на стороне сервера, как сеанс. В целях безопасности лучше хранить токены в файлах cookie HTTPOnly.
Почему запросы Cross-Origin блокируются?
Предположим, что наше внешнее приложение развернуто по адресу https://app.geekflare.com. Скрипт, загруженный в https://app.geekflare.com, может запрашивать только ресурсы того же происхождения.
Всякий раз, когда мы пытаемся отправить кросс-оригинальный запрос на другой домен https://api.geekflare.com или другой порт https://app.geekflare.com:3000 или другую схему http://app.geekflare.com, кросс-оригинальный запрос будет заблокирован браузером.
Но почему один и тот же запрос, заблокированный браузером, отправляется с любого бэкэнд-сервера с помощью curl-запроса или с помощью таких инструментов, как почтальон, без каких-либо проблем с CORS. На самом деле это необходимо для обеспечения безопасности, чтобы защитить пользователей от атак, таких как CSRF (подделка межсайтовых запросов).
Давайте возьмем пример, предположим, что любой пользователь вошел в свою учетную запись PayPal в своем браузере. Если мы можем отправить запрос о перекрестном происхождении на paypal.com из скрипта, загруженного в другом домене, без какой-либо ошибки/блокировки CORS, как если бы мы отправляли запрос с тем же источником.
Злоумышленники могут легко отправить свою вредоносную страницу https://malicious.com/transfer-money-to-attacker-account-from-user-paypal-account, преобразовав ее в короткий URL-адрес, чтобы скрыть фактический URL-адрес. Когда пользователь щелкнет вредоносную ссылку, скрипт, загруженный в домен malware.com, отправит запрос из разных источников в PayPal для перевода суммы пользователя на учетную запись PayPal злоумышленника. Все пользователи, которые вошли в свою учетную запись PayPal и перешли по этой вредоносной ссылке, потеряют свои деньги. Любой может легко украсть деньги без знания пользователя учетной записи PayPal.
По вышеуказанной причине браузеры блокируют все кросс-происходящие запросы.
Что такое CORS (обмен ресурсами между источниками)?
CORS — это механизм безопасности на основе заголовков, используемый сервером, чтобы указать браузеру отправить запрос из разных источников из доверенных доменов. Сервер с включенными заголовками CORS используется для предотвращения блокирования запросов из разных источников браузерами.
Как работает КОРС?
Поскольку сервер уже определил свой доверенный домен в своей конфигурации CORS. Когда мы отправляем запрос на сервер, ответ сообщает браузеру, является ли запрошенный домен доверенным или нет в его заголовке.
Существует два типа запросов CORS:
Простой запрос:
. В противном случае будет выдана ошибка CORS.
параметры для фактического запроса. Если параметры запроса разрешены сервером. Фактический запрос на кросс-начало, отправленный и полученный
Если access-control-allow-origin: *, то ответ разрешен для всех источников. Но это небезопасно, если вам это не нужно.
Как включить CORS?
Чтобы включить CORS для любого домена, включите заголовки CORS, чтобы разрешить источник, методы, настраиваемые заголовки, учетные данные и т. д.
Access-Control-Expose-Headers:
Укажите заголовки, доступные клиентскому сценарию.
Чтобы включить CORS на веб-сервере apache и Nginx, следуйте этому руководству.
Включение CORS в ExpressJS
Возьмем пример приложения ExpressJS без CORS:
константный экспресс = требуется (‘экспресс’); const app = express() app.get(‘/users’, function (req, res, next) { res.json({msg: ‘user get’}) }); app.post(‘/users’, function (req, res, next) { res.json({msg: ‘user create’}) }); app.put(‘/users’, function (req, res, next) { res.json({msg: ‘User update’}) }); app.listen(80, function () { console.log(‘Веб-сервер с поддержкой CORS прослушивает порт 80’) }) В приведенном выше примере мы включили конечную точку пользовательского API для методов POST, PUT, GET, но не для метода DELETE.
Чтобы упростить включение CORS в приложении ExpressJS, вы можете установить
кор
npm установить корс
Access-Control-Allow-Origin
Включение CORS для всего домена
app.use (cors ({ происхождение: ‘*’ }));
Включение CORS для одного домена app.use(cors({ происхождение: ‘https://app.geekflare.com’ })); Если вы хотите разрешить CORS для происхождения https://app.geekflare.com
а также [
‘https://app.geekflare.com’,
‘https://lab.geekflare.com’
]
https://lab.geekflare.com
app.use (cors ({ происхождение:
}));
Access-Control-Allow-Methods [
‘https://app.geekflare.com’,
‘https://lab.geekflare.com’
]Чтобы включить CORS для всех методов, опустите этот параметр в модуле CORS в файле ExpressJS. Но для включения определенных методов (GET, POST, PUT). [‘GET’, ‘PUT’, ‘POST’]
app.use (cors ({ происхождение:
методы:
}));
Access-Control-Allow-Headers [
‘https://app.geekflare.com’,
‘https://lab.geekflare.com’
]Используется, чтобы разрешить отправку заголовков, отличных от значений по умолчанию, с фактическими запросами. [‘GET’, ‘PUT’, ‘POST’]app.use (cors ({ происхождение: [‘Content-Type’, ‘Authorization’, ‘x-csrf-token’]
методы:
разрешеноЗаголовки:
})); Доступ-Контроль-Разрешить-Учетные данные Опустите это, если вы не хотите, чтобы браузер разрешал учетные данные по запросу даже нас учетными данными
установлено значение true [
‘https://app.geekflare.com’,
‘https://lab.geekflare.com’
]. [‘GET’, ‘PUT’, ‘POST’]app.use (cors ({ происхождение: [‘Content-Type’, ‘Authorization’, ‘x-csrf-token’]методы:
разрешеноЗаголовки:
учетные данные: правда }));
Access-Control-Max-Age [
‘https://app.geekflare.com’,
‘https://lab.geekflare.com’
]Чтобы указать браузеру кэшировать информацию об ответе предварительной проверки в кеше на указанную секунду. Опустите это, если вы не хотите кэшировать ответ. [‘GET’, ‘PUT’, ‘POST’]app.use (cors ({ происхождение: [‘Content-Type’, ‘Authorization’, ‘x-csrf-token’]методы:
разрешеноЗаголовки:
учетные данные: true, maxAge: 600 }));
Кэшированный предварительный ответ будет доступен в браузере в течение 10 минут. [
‘https://app.geekflare.com’,
‘https://lab.geekflare.com’
]Access-Control-Expose-Headers [‘GET’, ‘PUT’, ‘POST’]app.use (cors ({ происхождение: [‘Content-Type’, ‘Authorization’, ‘x-csrf-token’]методы: [‘Content-Range’, ‘X-Content-Range’]
разрешеноЗаголовки:
учетные данные: true, maxAge: 600, экспонированные заголовки: })); Если мы поместим подстановочный знак
в [
‘https://app.geekflare.com’,
‘https://lab.geekflare.com’
]открытые заголовки, [‘GET’, ‘PUT’, ‘POST’]он не будет отображать заголовок авторизации. Итак, мы должны явно указать, как показано ниже. [‘Content-Type’, ‘Authorization’, ‘x-csrf-token’]app.use (cors ({ происхождение: [‘*’, ‘Authorization’, ]
методы:
разрешеноЗаголовки:
учетные данные: true, maxAge: 600, экспонированные заголовки:
}));
Вышеприведенное также покажет все заголовки и заголовок авторизации.
тот же сайт (строка
): Используется для включения/ограничения файлов cookie, отправляемых при межсайтовых запросах. Чтобы узнать больше о файлах cookie sameSite, см. MDN. Он принимает три варианта Strict, Lax, None. Значение безопасности файлов cookie установлено равным true для конфигурации файлов cookie sameSite=None.Почему HTTPOnly cookie для токенов? Хранение токена доступа, отправленного с сервера, в хранилище на стороне клиента, например локальное хранилище , индексированная БД,
а также
печенье
(HTTPOnly не имеет значения true) более уязвимы для XSS-атак. Предположим, что какая-либо из ваших страниц уязвима для атаки XSS. Злоумышленники могут неправомерно использовать пользовательские токены, хранящиеся в браузере.
Файлы cookie HTTPOnly устанавливаются/получаются только сервером/бэкендом, но не на стороне клиента.
Access-Control-Allow-Origin и Access-Control-Allow-Headers не должны быть подстановочными знаками.
. [
‘https://app.geekflare.com’,
‘https://lab.geekflare.com’
]Атрибут cookie sameSite должен иметь значение None. [‘GET’, ‘PUT’, ‘POST’]Чтобы включить для параметра sameSite значение none, установите для безопасного значения значение true: Включить серверную часть с сертификатом SSL/TLS для работы с доменным именем. [‘Content-Type’, ‘Authorization’, ‘x-csrf-token’]Давайте посмотрим пример кода, который устанавливает маркер доступа в файле cookie HTTPOnly после проверки учетных данных для входа. [‘*’, ‘Authorization’ ]
константный экспресс = требуется (‘экспресс’); константное приложение = экспресс(); const cors = требуют(‘cors’); app.use (cors ({ происхождение:
методы:
разрешеноЗаголовки:
учетные данные: true, maxAge: 600, экспонированные заголовки:
})); app.post(‘/login’, function (req, res, next) { res.cookie(‘access_token’, access_token, { expires: new Date(Date.now() + (3600 * 1000 * 24 * 180 * 1 )) //второй мин час дней год secure: true, // установите значение true, если вы используете https или тот же сайт, но нет httpOnly: true, // только серверная часть sameSite: ‘none’ // установите значение none для перекрестного запроса } ); res.json({ msg: ‘Войти успешно’, access_token }); }); app.listen(80, function () { console.log(‘Веб-сервер с поддержкой CORS прослушивает порт 80’) });
Вы можете настроить файлы cookie CORS и HTTPOnly, выполнив указанные выше четыре шага на своем внутреннем языке и веб-сервере.
Вы можете следовать этому руководству для apache и Nginx для включения CORS, выполнив описанные выше шаги.
withCredentials для запроса перекрестного происхождения
Учетные данные (Cookie, авторизация) по умолчанию отправляются с запросом того же источника. Для перекрестного происхождения мы должны указать для withCredentials значение true.
XMLHttpRequest API
var xhr = новый XMLHttpRequest(); xhr.open(‘GET’, ‘http://api.geekflare.com/user’, true); xhr.withCredentials = истина; xhr.send(ноль);
Получить API
fetch(‘http://api.geekflare.com/user’, {учетные данные: ‘include’});
JQuery Аякс
$.ajax({url: ‘http://api.geekflare.com/user’, xhrFields: {withCredentials: true} });
Аксиосaxios.defaults.withCredentials = истинаВывод Я надеюсь, что приведенная выше статья поможет вам понять, как работает CORS, и включить CORS для запросов между источниками на сервере. Почему хранение файлов cookie в HTTPOnly является безопасным и как withCredentials используется в клиентах для запросов из разных источников.