Перейти до основного вмісту

Як розміщувати статичні файли на CDN за допомогою Casdoor: S3, MinIO, Azure Blob та інші провайдери сховища

· Читання за 10 хв
Yang Luo
Casdoor Maintainer

Щоб розміщувати статичні файли на CDN, помістіть їх у сховище об'єктів (Amazon S3, MinIO, Azure Blob Storage, Google Cloud Storage, Alibaba Cloud OSS або Tencent Cloud COS), зробіть так, щоб CDN витягував дані з цього бакета як свого origin, і надавайте URL-адреси на домені CDN. У Casdoor це один параметр: створіть провайдера сховища для бакета та вкажіть адресу CDN у його полі Domain. Casdoor завантажує аватари та інші файли через API провайдера та зберігає URL-адреси, що починаються з цього домену. Інтерфейс самого Casdoor також може подаватися з CDN через frontendCdnUrl та staticBaseUrl у app.conf.

Провайдери сховища в загальному вигляді​

Провайдер сховища визначає, куди Casdoor записує завантажені файли: аватари користувачів, зображення ID-карток, сторінки умов використання та будь-що, завантажене на сторінці Resources. Ви додаєте провайдера до додатка, і завантаження в цьому додатку йдуть до нього. Огляд провайдерів сховища перелічує всі типи. Ця таблиця охоплює ті, які найчастіше цікавлять:

СховищеТип провайдера CasdoorЧи використовує Casdoor S3 API?Можна розмістити самостійноЯк встановлюється публічна URL-адреса
Локальна файлова системаLocal File SystemНі, звичайні файли на дискуТак, це сервер CasdoorОбслуговується Casdoor за адресою /files/. Поле Domain доступне лише для читання
Amazon S3AWS S3ТакНіDomain: URL-адреса бакета або домен CloudFront. Endpoint (Intranet): кінцева точка VPC
MinIOMinIOТак, із запитами path-styleТакDomain: URL-адреса MinIO, за якою слідує ім'я бакета, або домен CDN
Alibaba Cloud OSSAliyun OSSНі, SDK OSSНіDomain: домен CDN. Якщо залишити порожнім, стане bucket.endpoint. Endpoint (Intranet): внутрішня кінцева точка
Tencent Cloud COSTencent Cloud COSНі, API COSНіDomain: домен CDN
Azure Blob StorageAzure BlobНі, API BlobНіDomain: власний домен або домен Front Door. Casdoor додає ім'я контейнера до шляху
Google Cloud StorageGoogle Cloud StorageНі, Go-клієнт GoogleНіDomain: якщо залишити порожнім, стає https://storage.googleapis.com. Casdoor додає ім'я бакета до шляху
NAS SynologySynologyНі, API DSM File StationТакНемає поля Domain. URL-адреса базується на Endpoint

Casdoor також підтримує Qiniu Cloud Kodo, CUCloud OSS та Casdoor, який зберігає файли в іншому екземплярі Casdoor. Посібники для окремих провайдерів — Amazon S3, MinIO, Azure Blob, Google Cloud Storage, Alibaba Cloud OSS, Tencent Cloud COS, NAS Synology та локальна файлова система — показують, яке значення в якому полі вказати.

Endpoint проти Domain​

Ці два поля виконують різні завдання, і більшість проблем із CDN виникають через їх плутанину.

  • Endpoint — це адреса, яку Casdoor використовує для спілкування з API сховища: завантаження, видалення, перегляд списку. CDN тут не задіяний.
  • Endpoint (Intranet) замінює Endpoint, коли в app.conf встановлено isCloudIntranet = true. Це дозволяє утримувати трафік завантаження в межах внутрішньої мережі провайдера, коли Casdoor працює в тій самій хмарі. Це поле доступне для AWS S3, Aliyun OSS, Azure Blob та CUCloud OSS.
  • Domain — це база URL-адреси, яку зберігає Casdoor і яку запитують браузери. Якщо у вас є CDN, його домен потрібно вказати тут.
  • Path prefix додається на початку кожного ключа об'єкта. З префіксом casdoor аватар буде збережено за шляхом casdoor/avatar/....

Casdoor формує URL-адресу файлу зі схеми та хоста Domain, потім шляху Domain, потім префіксу шляху, а потім шляху до файлу. Домен без схеми отримує префікс https://. Шляхова частина Domain також стає частиною ключа об'єкта, тому https://cdn.example.com/casdoor/ зберігає файли в директорії casdoor/ у бакеті. Для Azure Blob та Google Cloud Storage Casdoor додає ім'я контейнера або бакета як перший сегмент шляху після хоста. Ваш CDN повинен обслуговувати цей шлях.

Якщо Domain порожній, Casdoor заповнює його з ендпоінту провайдера при першому використанні провайдера та зберігає це значення. Іноді результат працює, як у випадку з OSS та GCS. Іноді ні: для ендпоінту S3 без імені бакета або для MinIO, де запити path-style розміщують ім'я бакета в шляху, згенерована URL-адреса не містить бакета. Вкажіть Domain вручну, завантажте один тестовий аватар і відкрийте URL-адресу, яку повернув Casdoor, перш ніж цим скористаються інші.

Провайдер, який Casdoor використовує для аватарів, скопійованих із соціальних логінів, визначається параметром defaultStorageProvider у app.conf. Це ім'я провайдера, що належить admin (див. довідник конфігурації):

defaultStorageProvider = provider_storage_s3
isCloudIntranet = false

Публічні бакети, приватні бакети та підписані URL-адреси​

Casdoor зберігає одну просту, постійну URL-адресу в полі avatar користувача та в записі ресурсу. Він не створює підписані або термінові URL-адреси для цих файлів. Тому все, що знаходиться за адресою Domain, повинно відповідати на анонімний запит GET. Є два способи зробити це.

Зробіть об'єкти публічними. Для AWS S3 та MinIO Casdoor завантажує кожен об'єкт із канонічним ACL public-read. Для Aliyun OSS клієнтська бібліотека робить те саме за замовчуванням. У S3 це конфліктує з налаштуваннями нових бакетів за замовчуванням: згідно з AWS, нові бакети використовують налаштування Bucket owner enforced, яке вимикає ACL, і завантаження, що встановлює ACL на кшталт public-read, завершується помилкою AccessControlListNotSupported. Саме тому в посібнику Amazon S3 рекомендується увімкнути ACL та вимкнути Block all public access. В OSS ACL об'єкта має перевагу над ACL бакета, тому об'єкт public-read можна прочитати навіть у приватному бакеті. MinIO не використовує ACL для анонімного читання. Він використовує політику бакета:

mc anonymous set download myminio/casdoor

Azure потребує дозволу анонімного доступу на рівні облікового запису сховища та встановлення рівня доступу контейнера на Blob. Google Cloud Storage потребує надання ролі Storage Object Viewer (roles/storage.objectViewer) для allUsers на рівні бакета.

Залиште бакет приватним і дозвольте читати його лише через CDN. CDN підписує свої запити до origin-сервера, а переглядачі отримують доступ через CDN без підпису. Кожен вендор має свою версію цього рішення:

  • CloudFront має контроль доступу до origin (OAC). AWS вимагає Bucket owner enforced для OAC, або Bucket owner preferred, якщо вам потрібні ACL.
  • Alibaba Cloud CDN може отримувати дані з приватного бакета OSS після авторизації.
  • Tencent Cloud CDN має автентифікацію origin-pull для приватних бакетів COS.
  • Azure Front Door Premium може отримувати доступ до облікового запису сховища через Private Link.
  • Посібник Google Cloud CDN також охоплює доступ до приватних бакетів, де роль Storage Object Viewer надається сервісному обліковому запису замість allUsers.

Це приховує власну URL-адресу бакета, але файли залишаються публічно доступними через CDN. Для типів AWS S3 та Aliyun OSS об'єкти також залишаються доступними для читання за їхніми URL-адресами бакета через ACL public-read, який встановлює Casdoor.

Якщо аватари взагалі не повинні бути публічними, CDN перед сховищем об'єктів — неправильний інструмент. Зберігайте ці файли на керованому вами типі сховища та обмежуйте коло осіб, які можуть отримати доступ до цього хоста.

Заголовки кешування та проблема з аватарами​

У S3 та MinIO Casdoor встановлює Content-Type на основі розширення файлу під час завантаження. Він не встановлює Cache-Control жодному провайдеру. Це означає, що діє TTL CDN за замовчуванням. У CloudFront об'єкти без Cache-Control кешуються на TTL за замовчуванням, який становить 24 години, якщо ви не використовуєте політику кешування. Щоб контролювати це для кожного об'єкта, додайте метадані Cache-Control у бакеті. Для всього шляху використовуйте правило кешування на рівні CDN.

Аватари потребують короткого TTL. Коли користувач змінює своє зображення, Casdoor записує новий файл за тим самим ключем avatar/<organization>/<username>.<extension> та зберігає ту саму URL-адресу. Довгий TTL означає, що люди бачитимуть старе зображення, доки воно не застаріє або доки ви не очистите чи не скасуєте кешування цього шляху. Інші завантаження отримують числовий суфікс (-1, -2, ...), якщо ім'я вже зайняте, тому нове завантаження отримує нову URL-адресу і може кешуватися довго.

Робоча схема:

ШляхРекомендоване кешування
avatar/*Короткий TTL (хвилини) або очищення кешу при зміні
resource/* та інші завантаженняДовгий TTL
Хешовані фронтенд-ресурси (assets/*)Дуже довгий TTL. Ім'я файлу змінюється при кожній збірці

Власний фронтенд Casdoor на CDN​

Окремо від завантажень користувачів, існує три способи перенести власні статичні файли Casdoor з сервера Casdoor.

frontendCdnUrl. Використовуйте цей параметр, якщо ви встановлюєте фронтенд з npm-пакета casdoor-web. Вкажіть на нього npm CDN, наприклад:

frontendCdnUrl = "https://cdn.jsdelivr.net/npm/{name}@{version}"

Casdoor читає назву пакета та версію з package.json у папці збірки. Він переписує посилання на скрипти та стилі в index.html на цей CDN і зберігає локальні шляхи як резервний варіант. Якщо файл не вдається завантажити, браузер завантажує його з Casdoor, а cookie утримує цей браузер на локальних файлах до кінця сесії. Фронтенд, зібраний вами вручну, не має такого package.json, тому ця настройка на нього не впливає.

Скрипт розгортання. Для фронтенду, який ви збираєте з вихідного коду, у статті Розміщення файлів фронтенду на CDN пояснюється робота deployment/deploy_test.go. Він завантажує web/build/assets/ через один із ваших постачальників сховища та вказує index.html на Domain постачальника, який має закінчуватися на /. Vite хешує ці імена файлів, тому вони підходять для довгого TTL, зазначеного в таблиці вище.

staticBaseUrl. Визначає, звідки надходять зображення за замовчуванням, такі як логотипи, іконки провайдерів та аватар за замовчуванням. За замовчуванням використовується https://cdn.casbin.org, який обслуговує репозиторій casbin/static. У мережі без доступу до Інтернету розмістіть власну копію цього репозиторію та вкажіть staticBaseUrl на неї, як описано в Розміщення статичних файлів у внутрішній мережі.

Вибір одного варіанту​

  • Один сервер, мала база користувачів: Local File System. Змонтируйте каталог files на том, якщо Casdoor працює в контейнері. Casdoor надсилає X-Content-Type-Options: nosniff та пісочницю Content-Security-Policy для цих файлів, тому завантажений HTML- або SVG-файл не може виконувати скрипти на вашому домені Casdoor.
  • Self-hosted та сумісний із S3: MinIO. Це також тип, який документація рекомендує для інших сховищ, сумісних із S3.
  • Вже використовуєте хмару: скористайтеся об'єктним сховищем та CDN цієї хмари, вкажіть Endpoint (Intranet), де Casdoor працює в тій самій хмарі, а Domain — на CDN.

Посилання​