Секретний API-ключ у застосунку Expo: що захищати
Автор: Mehdi Azizi
Оновлено , 7 хв
Публічний ключ Supabase, серверний секрет, змінні Expo: розберись, що можна вкласти в iPhone-застосунок, і перевір доступи двома акаунтами.
Змінна середовища не обов'язково є секретом
У застосунку Expo змінна з префіксом EXPO_PUBLIC_ призначена для коду застосунку. Серверного секрету в ній бути не повинно. Expo пояснює, що ці значення вбудовуються в скомпільований JavaScript і їх можуть прочитати користувачі застосунку. Тож просто перенести ключ у файл .env недостатньо, щоб його захистити. Джерело: змінні середовища Expo.
Перш ніж просити ШІ «підключити API», розклади по поличках те, що ти йому даєш: адреса сервісу, ключ, який задумано публічним, чи ключ, що дозволяє привілейовані дії. Від цього залежить, де має виконуватися код.
Таблиця нижче є схемою для проєктування, а не аудитом твого застосунку.
| Елемент | Де його розмістити | Що перевірити |
|---|---|---|
| Публічна адреса бекенду | Конфігурація застосунку | Вона вказує на потрібне середовище. |
| Ключ Supabase publishable або старий ключ anon | Застосунок, якщо дозволи налаштовано правильно | Правила доступу до даних справді блокують доступ до акаунта іншого користувача. |
| Ключ Supabase secret або service_role | Лише сервер | Його немає ні в мобільному бандлі, ні в журналах, доступних клієнту. |
| Секретний ключ постачальника ШІ | Лише сервер | Застосунок звертається до твого сервера, який перевіряє користувача й ліміти перед постачальником. |
Supabase розрізняє ключі для клієнтів і секретні ключі для довірених середовищ. Публічний ключ ідентифікує проєкт, але не замінює дозволів на дані. Джерело: API-ключі Supabase.
Приклад: вигаданий застосунок-щоденник читання
Уявімо застосунок, у якому Ліна й Сашко зберігають свої книжки та приватні нотатки. Цей приклад потрібен, щоб підготувати тести. Він не описує результатів, отриманих на застосунку Devoria.
Звичайний сценарій виглядає нормально: Ліна входить і бачить свої нотатки. Але це ще не відповідає на головне питання: чи відхилить сервер запит Ліни до нотатки Сашка?
Фільтр в інтерфейсі на кшталт «показувати нотатки поточного користувача» покращує відображення. Але авторизацію треба застосовувати й на рівні даних. У Supabase правила Row Level Security дають змогу обмежити доступні рядки залежно від сесії. Supabase радить вмикати їх для таблиць, відкритих через API, і пояснює політики читання та запису. Джерело: Row Level Security.
У власному тестовому проєкті прив'яжи кожну нотатку до її власника й окремо визнач, хто може її читати, створювати, змінювати та видаляти. Перевір і файли: захищений рядок у базі даних не доводить, що зображення приватне.
Сценарій перевірки з двома тестовими акаунтами
Підготуй два акаунти, які ти контролюєш, по різній книжці в кожному й коротку впізнавану нотатку. Використовуй вигадані дані в дозволеному тестовому середовищі.
- Прочитати свою нотатку. Акаунт A бачить нотатку A.
- Прочитати нотатку B з акаунта A. Запит не розкриває її приватний вміст.
- Змінити нотатку B з акаунта A. Сервер відмовляє, нотатка B лишається без змін.
- Створити запис від імені B з акаунта A. Сервер відхиляє таке призначення.
- Прочитати без сесії. Жодного приватного вмісту не повертається.
- Відкрити приватний файл B з акаунта A. Файл недоступний.
Записуй фактичний результат, протестовану версію та помилку, якщо вона була. «Правила ввімкнено» не є результатом тесту. Шаблон перевірки в ресурсах можна взяти за основу, щоб зберігати ці докази.
Пропускай платні виклики через свій сервер
Для функції, яка робить короткий виклад книжки через API ШІ, маршрут може бути таким: застосунок → твій сервер → постачальник → твій сервер → застосунок. Секретний ключ лишається на сервері. Але сама лише така архітектура не рятує: доступ до сервера теж треба контролювати.
У вигаданому прикладі сервер має, зокрема, перевірити сесію, перевірити, що книжка належить цій людині, обмежити повторні запити й повернути зрозумілу помилку, якщо постачальник не відповідає. Клієнт не вирішує сам, чи має користувач платний доступ.
Підготуй чотири перевірки: користувач не ввійшов, книжка іншого акаунта, ліміт вичерпано, постачальник недоступний. Остання дає змогу перевірити, що застосунок виходить зі стану завантаження й не губить введений текст.
Що можна попросити у свого асистента для коду
Ось інструкція для рев'ю, яку можна адаптувати під свій репозиторій. Не вставляй у неї свої секретні значення:
Перелічи змінні, які використовують мобільний код і сервер, показуючи лише їхні назви. Знайди привілейовані виклики на боці клієнта. Для приватних даних опиши перевірки читання й запису, а потім запропонуй сценарій перевірки з двома тестовими акаунтами. Не виконуй ротацію ключів і не змінюй продакшн без підтвердження.
Читай відповідь разом із відповідним кодом. Асистент може помітити невідповідність, але його відповідь не замінює запуску тестів. Посібник створити застосунок із Claude Code пояснює, як розбити цю роботу на частини.
Перш ніж рухатися далі
Ти маєш уміти просто пояснити три речі: які значення публічні, які операції йдуть через сервер і які тести показують, що один акаунт не бачить даних іншого. Якщо щось із цього лишається туманним, проясни це, перш ніж додавати нові функції.
Сторінка створити застосунок для iPhone показує місце цього етапу в повному проєкті. Щоб рухатися по порядку, iOS Kit пропонує шлях із чотирьох етапів і стартовий код, де вже є акаунти та ШІ. Якщо не знаєш, з якого етапу продовжити, безкоштовна діагностика впорядкує твій проєкт і надішле тобі мій чекліст проти відмов 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. Зроби також перевірки без сесії: кожен запит має бути відхилений або нічого не розкривати. Записуй фактичний результат, бо «правила ввімкнено» не є результатом тесту.
Як попросити ШІ перевірити ключі мого застосунку?
Попроси його перелічити змінні мобільного коду й сервера, показуючи лише їхні назви, і не вставляй свої секретні значення. Також попроси знайти привілейовані виклики на боці клієнта й запропонувати сценарій перевірки з двома тестовими акаунтами. Заборони будь-яку ротацію ключів чи зміни в продакшні без підтвердження. Його відповідь не замінює запуску тестів.