CloudFront 403 с signed cookies для Vue SPA на S3: как исправить
Почему возникает ошибка CloudFront 403 при signed cookies в Amazon CloudFront для Vue SPA на S3? Настройка Lambda@Edge, custom policy, behaviors для dev/prod, атрибуты куки Domain/Path. Пошаговое решение cloudfront block и 403 request blocked с примерами кода.
Почему возникает ошибка ‘Access denied’ при использовании signed cookies в CloudFront для Vue SPA на S3? Lambda@Edge на пути /auth выдает редирект с куки (CloudFront-Policy, CloudFront-Signature, CloudFront-Key-Pair-Id), но доступ к ресурсам запрещен. Default behavior указывает на S3 origin с папкой prod/. Как правильно настроить политику, куки и поведения для доступа к dev-приложениям на отдельных CloudFront-доменах?
Ошибка cloudfront 403 “Access denied” в Amazon CloudFront с signed cookies обычно возникает из-за несоответствия домена, пути в политике или поведениях дистрибутива, когда Lambda@Edge генерирует куки, но они не проходят верификацию для dev-ресурсов Vue SPA на S3. Default behavior с origin prod/ блокирует доступ к /dev/, поэтому настройте отдельные behaviors для dev/prod с Forward Cookies: All и Restrict Viewer Access на Trusted Key Groups. Правильная custom policy в куки должна включать Resource вроде “https://dev.d123.cloudfront.net/dev/*”, а атрибуты Set-Cookie — Domain=dev.d123.cloudfront.net, Path=/dev/.
Содержание
- Почему возникает ошибка cloudfront 403 при signed cookies в CloudFront
- Настройка Lambda@Edge для /auth и генерации cloudfront cookies
- Создание custom policy для amazon cloudfront с Resource и DateLessThan
- Конфигурация CloudFront behaviors для dev/prod S3 origins
- Атрибуты куки: Domain, Path, Secure, HttpOnly для cloudfront 403 error
- Проверка и отладка cloudfront block и cloudfront 403 request blocked
- Деплой Lambda@Edge и propagation в дистрибутиве aws cloudfront
- Лучшие практики для Vue SPA на S3 с signed cookies
- Источники
- Заключение
Почему возникает ошибка cloudfront 403 при signed cookies в CloudFront
Представьте: вы заходите на /auth, Lambda@Edge шлёт редирект с куки CloudFront-Policy, Signature и Key-Pair-Id. А потом — бац! Cloudfront 403 error “Access denied”. Почему это происходит именно с dev-приложениями Vue SPA на S3?
Всё дело в верификации. CloudFront проверяет signed cookies строго: политика (base64 JSON) должна точно совпадать с запрашиваемым ресурсом, временем и ключом. Если default behavior ведёт на S3 origin с папкой prod/, а вы пытаетесь достать /dev/index.html, то Resource в политике не матчит — и вот вам cloudfront block. Плюс, куки могут не передаваться из-за Path=/prod/ или Domain не для dev-домена.
Ещё ловушка: без Forward Cookies в behavior куки просто игнорируются. Или IP из России/другой страны не входит в policy, если указали IPAddressRange. А propagation Lambda@Edge занимает до 15 минут — ждёте, а кажется, ничего не меняется.
Согласно документации Amazon CloudFront, cloudfront 403 request blocked часто из-за неверного формата политики или отсутствия Restrict Viewer Access.
Настройка Lambda@Edge для /auth и генерации cloudfront cookies
Lambda@Edge — ваш герой здесь. Создайте функцию на viewer-request для пути /auth*. В ней генерируйте редирект 302 на главную, прикрепив signed cookies.
Вот пример кода на JS (Node.js runtime):
exports.handler = async (event) => {
const request = event.Records[0].cf.request;
if (request.uri.startsWith('/auth')) {
const response = {
status: '302',
statusDescription: 'Found',
headers: {
location: [{ key: 'Location', value: '/' }],
'set-cookie': [
{ key: 'Set-Cookie', value: 'CloudFront-Policy=BASE64_POLICY; Domain=dev.d123.cloudfront.net; Path=/dev/; Secure; HttpOnly; SameSite=Lax' },
{ key: 'Set-Cookie', value: 'CloudFront-Signature=BASE64_SIGNATURE; Domain=dev.d123.cloudfront.net; Path=/dev/; Secure; HttpOnly; SameSite=Lax' },
{ key: 'Set-Cookie', value: 'CloudFront-Key-Pair-Id=YOUR_KEY_PAIR_ID; Domain=dev.d123.cloudfront.net; Path=/dev/; Secure; HttpOnly; SameSite=Lax' }
]
}
};
return response;
}
return request;
};
Подставьте реальные значения policy/signature, сгенерированные заранее или динамически (используйте crypto для подписи). Это решит проблему, когда после /auth доступ к dev-ресурсам всё равно даёт cloudfront 403.
Подробности в блоге AWS от Aleksandar Tolev.
Создание custom policy для amazon cloudfront с Resource и DateLessThan
Политика — сердце signed cookies. JSON должен быть одной Statement без лишних пробелов, base64-кодирован.
Пример для dev:
{
"Statement": [{
"Resource": "https://dev.d123.cloudfront.net/dev/*",
"Condition": {
"DateLessThan": {"AWS:EpochTime": 1735689600},
"IpAddress": {"AWS:SourceIp": "YOUR_IP/32"}
}
}]
}
Кодируйте: echo -n 'JSON' | base64. Resource точно как URL в запросе — с протоколом и доменом dev. DateLessThan в секундах UTC. Без этого cloudfront заблокирован навсегда.
Для prod меняйте Resource на /prod/*. Генерируйте подпись приватным ключом из Key Pair.
AWS re:Post советует декодировать policy для проверки: echo BASE64 | base64 -d | tr '[:space:]' '\n'.
Конфигурация CloudFront behaviors для dev/prod S3 origins
Default behavior на prod/ — корень зла. Создайте два behaviors:
- Path Pattern: /dev/* → Origin: S3 bucket с папкой dev/, Restrict Viewer Access: Yes, Trusted Key Groups: ваш group.
- Path Pattern: /prod/* → Аналогично для prod/.
- Default (/* → prod/, но с /auth* на Lambda@Edge.
В каждом: Cache Policy с Forward Cookies: All (Whitelist: CloudFront-*). Origin Path: /dev/ или /prod/.
Для отдельных доменов (dev.cloudfront.net, prod.cloudfront.net) — два дистрибутива, каждый со своим behavior и Lambda ARN.
Это обходит cloudfront 403 error для dev-приложений.
Атрибуты куки: Domain, Path, Secure, HttpOnly для cloudfront 403 error
Куки игнорируются без правильных атрибутов. Domain=dev.d123.cloudfront.net (не .cloudfront.net!). Path=/dev/ (матчит запросы). Secure=true для HTTPS, HttpOnly для защиты от JS, SameSite=Lax против CSRF.
Пример Set-Cookie: CloudFront-Policy=...; Domain=dev.example.cloudfront.net; Path=/dev/; Secure; HttpOnly; SameSite=Lax
Без Path=/dev/ куки не уйдут на /dev/assets.js — привет, cloudfront block. Тестируйте в DevTools: Network → Cookies.
Документация Amazon CloudFront подчёркивает: куки работают только в пределах Domain/Path.
Проверка и отладка cloudfront block и cloudfront 403 request blocked
Cloudfront 403? Шаги:
- DevTools: куки присутствуют? Атрибуты верны?
- Декодируйте Policy:
echo POLICY | base64 --decode | jq . - CloudFront Logs: включите и ищите “InvalidPolicy” или “SignatureDoesNotMatch”.
curl -I -H "Cookie: CloudFront-Policy=...;" https://dev.d123.cloudfront.net/dev/— 403?- Проверьте Key Pair в Trusted Key Groups.
Если IPv6 — проблема, используйте IPv4 в policy. Propagation? Подождите 15 мин.
Из AWS re:Post: часто виноват лишний символ в JSON.
Деплой Lambda@Edge и propagation в дистрибутиве aws cloudfront
- Создайте Lambda в us-east-1 (регион CloudFront).
- Publish version, скопируйте ARN.
- В дистрибутиве: Behaviors → Edit → Lambda Function Associations → Viewer Request: ARN.
- Save → ждите invalidation (5-15 мин).
Для репликации в регионы — автоматом. Тестируйте на staging-домене.
Bлог AWS описывает полный деплой для SPA.
Лучшие практики для Vue SPA на S3 с signed cookies
- Отдельные дистрибутивы для dev/prod — проще масштабировать.
- Dynamic policy в Lambda: генерируйте на лету по IP/user.
- S3 Bucket Policy: DenyAll + Allow от CloudFront ARN.
- Vue Router: history mode с /dev/ prefix.
- Rotate keys регулярно.
- Мониторинг: CloudWatch на 403 ошибки.
Это сделает ваш setup надёжным, без amazon cloudfront блокирует доступ.
Источники
- Amazon CloudFront — Документация по настройке signed cookies и защиты private content: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-cookies.html
- AWS re:Post — Руководство по устранению ошибок cloudfront 403 с signed cookies и URLs: https://repost.aws/knowledge-center/cloudfront-troubleshoot-signed-url-cookies
- Signed cookie-based authentication with Amazon CloudFront and AWS Lambda@Edge (Part 2) — Блог о реализации авторизации для SPA с примерами Lambda и политик: https://aws.amazon.com/blogs/networking-and-content-delivery/signed-cookie-based-authentication-with-amazon-cloudfront-and-aws-lambdaedge-part-2-authorization/
Заключение
Настройка signed cookies в CloudFront для Vue SPA на S3 сводится к точному матчингу policy Resource с behaviors dev/prod, правильным атрибутам куки (Domain/Path) и Forward Cookies: All. После фикса Lambda@Edge редиректа и деплоя cloudfront 403 уйдёт, открыв доступ к dev-ресурсам без блокировок. Протестируйте шаг за шагом — и ваш дистрибутив aws cloudfront заработает как часы.
Ошибка cloudfront 403 ‘Access denied’ возникает, когда signed cookies не передаются корректно из-за несоответствия домена и пути. Для dev-приложений создайте отдельное cache behavior с origin-путём /dev/, включите Forward Cookies: All и Restrict Viewer Access с Trusted Key Groups. В Lambda@Edge на пути /auth генерируйте редирект 302 с куки CloudFront-Policy, CloudFront-Signature, CloudFront-Key-Pair-Id, указав Domain=dev.cloudfront.net, Path=/, Secure и HttpOnly. Custom policy должна содержать Resource для dev-ресурсов и IPAddressRange при необходимости. После верификации ключом CloudFront отдаст файлы из S3 без cloudfront block.
Cloudfront 403 error возникает из-за неверной верификации signed cookies: проверьте CloudFront-Key-Pair-ID, наличие одной Statement в политике без лишних символов, корректный Resource (полный URL) и формат времени (AWS:EpochTime). Убедитесь, что Set-Cookie имеет правильные Domain и Path, IP не IPv6, и куки forwardятся. Декодируйте policy base64 для проверки: команды tr и base64 покажут JSON. Настройте S3 policy с Condition AWS:SourceArn на дистрибутив amazon cloudfront, чтобы избежать cloudfront 403 request blocked.
- Используйте Unix time в секундах для
DateLessThan. - Проверьте кодировку URL-safe base64 без padding.
Для Vue SPA на S3 настройте отдельный дистрибутив cloudfront или behavior для dev с Lambda@Edge на viewer-request /auth, генерирующим custom policy JSON: Resource "http*://dev-domain.cloudfront.net/*", DateLessThan. Редирект 302 с Set-Cookie (Policy, Signature, Key-Pair-Id) + Domain=dev-domain, Path=/, Secure, HttpOnly, SameSite=Lax. Default behavior не должен перекрывать /auth; ждите 5-15 мин propagation после деплоя Lambda@Edge. Это решит cloudfront 403 при доступе к защищённым ресурсам после аутентификации.

