# Секретний API-ключ у застосунку Expo: що захищати

> Публічний ключ Supabase, серверний секрет, змінні Expo: розберись, що можна вкласти в iPhone-застосунок, і перевір доступи двома акаунтами.

Оригінальна сторінка: [Секретний API-ключ у застосунку Expo: що захищати](https://devoria.fr/uk/blog/secret-api-key-expo-app-what-to-protect)
Автор: [Mehdi Azizi](https://devoria.fr/uk/mehdi-azizi)
Опубліковано: 2026-09-29
Останнє оновлення змісту: 2026-10-09


## Змінна середовища не обов'язково є секретом

У застосунку Expo змінна з префіксом `EXPO_PUBLIC_` призначена для коду застосунку. Серверного секрету в ній бути не повинно. Expo пояснює, що ці значення вбудовуються в скомпільований JavaScript і їх можуть прочитати користувачі застосунку. Тож просто перенести ключ у файл `.env` недостатньо, щоб його захистити. [Джерело: змінні середовища Expo](https://docs.expo.dev/guides/environment-variables/).

Перш ніж просити ШІ «підключити API», розклади по поличках те, що ти йому даєш: адреса сервісу, ключ, який задумано публічним, чи ключ, що дозволяє привілейовані дії. Від цього залежить, де має виконуватися код.

Таблиця нижче є схемою для проєктування, а не аудитом твого застосунку.

| Елемент                                        | Де його розмістити                             | Що перевірити                                                                                      |
| ---------------------------------------------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| Публічна адреса бекенду                        | Конфігурація застосунку                        | Вона вказує на потрібне середовище.                                                                |
| Ключ Supabase publishable або старий ключ anon | Застосунок, якщо дозволи налаштовано правильно | Правила доступу до даних справді блокують доступ до акаунта іншого користувача.                    |
| Ключ Supabase secret або service_role          | Лише сервер                                    | Його немає ні в мобільному бандлі, ні в журналах, доступних клієнту.                               |
| Секретний ключ постачальника ШІ                | Лише сервер                                    | Застосунок звертається до твого сервера, який перевіряє користувача й ліміти перед постачальником. |

Supabase розрізняє ключі для клієнтів і секретні ключі для довірених середовищ. Публічний ключ ідентифікує проєкт, але не замінює дозволів на дані. [Джерело: API-ключі Supabase](https://supabase.com/docs/guides/getting-started/api-keys).

## Приклад: вигаданий застосунок-щоденник читання

Уявімо застосунок, у якому Ліна й Сашко зберігають свої книжки та приватні нотатки. Цей приклад потрібен, щоб підготувати тести. Він не описує результатів, отриманих на застосунку Devoria.

Звичайний сценарій виглядає нормально: Ліна входить і бачить свої нотатки. Але це ще не відповідає на головне питання: чи відхилить сервер запит Ліни до нотатки Сашка?

Фільтр в інтерфейсі на кшталт «показувати нотатки поточного користувача» покращує відображення. Але авторизацію треба застосовувати й на рівні даних. У Supabase правила Row Level Security дають змогу обмежити доступні рядки залежно від сесії. Supabase радить вмикати їх для таблиць, відкритих через API, і пояснює політики читання та запису. [Джерело: Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security).

У власному тестовому проєкті прив'яжи кожну нотатку до її власника й окремо визнач, хто може її читати, створювати, змінювати та видаляти. Перевір і файли: захищений рядок у базі даних не доводить, що зображення приватне.

## Сценарій перевірки з двома тестовими акаунтами

Підготуй два акаунти, які ти контролюєш, по різній книжці в кожному й коротку впізнавану нотатку. Використовуй вигадані дані в дозволеному тестовому середовищі.

1. **Прочитати свою нотатку.** Акаунт A бачить нотатку A.
2. **Прочитати нотатку B з акаунта A.** Запит не розкриває її приватний вміст.
3. **Змінити нотатку B з акаунта A.** Сервер відмовляє, нотатка B лишається без змін.
4. **Створити запис від імені B з акаунта A.** Сервер відхиляє таке призначення.
5. **Прочитати без сесії.** Жодного приватного вмісту не повертається.
6. **Відкрити приватний файл B з акаунта A.** Файл недоступний.

Записуй фактичний результат, протестовану версію та помилку, якщо вона була. «Правила ввімкнено» не є результатом тесту. [Шаблон перевірки в ресурсах](https://devoria.fr/uk/resources) можна взяти за основу, щоб зберігати ці докази.

## Пропускай платні виклики через свій сервер

Для функції, яка робить короткий виклад книжки через [API ШІ](https://devoria.fr/uk/blog/guideline-5-1-2-third-party-ai-att-data-sharing), маршрут може бути таким: застосунок → твій сервер → постачальник → твій сервер → застосунок. Секретний ключ лишається на сервері. Але сама лише така архітектура не рятує: доступ до сервера теж треба контролювати.

У вигаданому прикладі сервер має, зокрема, перевірити сесію, перевірити, що книжка належить цій людині, обмежити повторні запити й повернути зрозумілу помилку, якщо постачальник не відповідає. Клієнт не вирішує сам, чи має користувач платний доступ.

Підготуй чотири перевірки: користувач не ввійшов, книжка іншого акаунта, ліміт вичерпано, постачальник недоступний. Остання дає змогу перевірити, що застосунок виходить зі стану завантаження й не губить введений текст.

## Що можна попросити у свого асистента для коду

Ось інструкція для рев'ю, яку можна адаптувати під свій репозиторій. Не вставляй у неї свої секретні значення:

> Перелічи змінні, які використовують мобільний код і сервер, показуючи лише їхні назви. Знайди привілейовані виклики на боці клієнта. Для приватних даних опиши перевірки читання й запису, а потім запропонуй сценарій перевірки з двома тестовими акаунтами. Не виконуй ротацію ключів і не змінюй продакшн без підтвердження.

Читай відповідь разом із відповідним кодом. Асистент може помітити невідповідність, але його відповідь не замінює запуску тестів. Посібник [створити застосунок із Claude Code](https://devoria.fr/uk/blog/stvoryty-zastosunok-claude-code-iphone-tutorial) пояснює, як розбити цю роботу на частини.

## Перш ніж рухатися далі

Ти маєш уміти просто пояснити три речі: які значення публічні, які операції йдуть через сервер і які тести показують, що один акаунт не бачить даних іншого. Якщо щось із цього лишається туманним, проясни це, перш ніж додавати нові функції.

Сторінка [створити застосунок для iPhone](https://devoria.fr/uk/expertise/create-an-iphone-app) показує місце цього етапу в повному проєкті. Щоб рухатися по порядку, [iOS Kit](https://devoria.fr/uk/kits/ios) пропонує шлях із чотирьох етапів і стартовий код, де вже є акаунти та ШІ. Якщо не знаєш, з якого етапу продовжити, [безкоштовна діагностика](https://devoria.fr/uk/diagnostic) впорядкує твій проєкт і надішле тобі мій чекліст проти відмов Apple.

## Поширені запитання

### Де зберігати секретний API-ключ у застосунку Expo?

На своєму сервері, ніколи в застосунку. Ключ Supabase secret або service_role, як і секретний ключ постачальника ШІ, має бути лише на сервері. Застосунок звертається до твого сервера, який перевіряє користувача й ліміти, перш ніж викликати постачальника. Переконайся, що жодного з цих ключів немає ні в мобільному бандлі, ні в журналах, доступних клієнту.

### Чи захищає файл .env мій API-ключ в Expo?

Сам по собі ні. Змінна з префіксом `EXPO_PUBLIC_` призначена для коду застосунку й не повинна містити серверного секрету. Expo пояснює, що ці значення вбудовуються в скомпільований JavaScript і їх можуть прочитати користувачі застосунку. Тож просто перенести ключ у файл `.env` недостатньо, щоб його захистити.

### Яка різниця між публічним і секретним API-ключем?

Публічний ключ задумано для постачання в застосунку: він ідентифікує проєкт, але не замінює дозволів на дані. Секретний ключ дозволяє привілейовані дії й призначений лише для довірених середовищ. У Supabase ключ publishable або старий ключ anon може лишатися в застосунку, якщо дозволи налаштовано правильно. Ключі secret і service_role лишаються на сервері.

### Як викликати API ШІ із застосунку Expo, не розкриваючи ключ?

Пропускай виклик через свій сервер: застосунок звертається до сервера, той викликає постачальника й повертає відповідь застосунку. Секретний ключ лишається на сервері. Сервер також має перевіряти сесію, обмежувати повторні запити й повертати зрозумілу помилку, якщо постачальник не відповідає. Клієнт не вирішує сам, чи має користувач платний доступ.

### Як перевірити, що кожен користувач бачить лише свої дані?

Підготуй два тестові акаунти, які ти контролюєш, із впізнаваною нотаткою в кожному. З акаунта A спробуй прочитати, змінити й створити запис від імені акаунта B, а потім відкрити приватний файл B. Зроби також перевірки без сесії: кожен запит має бути відхилений або нічого не розкривати. Записуй фактичний результат, бо «правила ввімкнено» не є результатом тесту.

### Як попросити ШІ перевірити ключі мого застосунку?

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


## Твій проєкт

[iOS Kit](https://devoria.fr/uk/kits/ios): Створи застосунок для iPhone з Claude Code: стартовий код моїх застосунків, skills, що перевіряють його роботу, а також Apple Review Kit, App Store Screenshots Kit і ASO Kit. 129,99 €.
