You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Expo/React Native环境下API密钥与密钥的安全存储方案咨询

安全存储Expo/React Native应用API密钥的解决方案

Hey there, let's break down how to securely store your API keys for your Expo/React Native app—since you've already built the app and just need to solve this security hurdle before launching, I'll give you practical, actionable solutions:

核心前提:前端存储不安全

First off, let's get one thing straight: any method that stores secrets directly in your frontend app isn't truly secure. APK/IPA files can be decompiled, and tools like react-native-dotenv just bake those keys into your final bundle—someone with basic reverse-engineering skills can pull them out easily. So for high-sensitivity secrets like SendGrid/Mailjet's API secret (which lets anyone send emails using your account), you absolutely need a middleman to handle the API calls.

无需完整后端的简便方案(快速上线首选)

If you don't want to set up and maintain a full backend, these lightweight options work great:

  • Serverless Functions
    This is the most recommended quick fix. You don't need to manage a server—just write simple functions to forward your API requests, with keys stored safely in the cloud provider's environment variables (never exposed to the frontend).
    For example, using platforms like Vercel or Netlify:

    1. Create a function (e.g., api/send-email.js) that handles calling SendGrid's API. Store your SendGrid secret key in the platform's environment settings (not in your code).
    2. For Google Places API:
      • If you're using the Web Service API, forward requests through a serverless function the same way.
      • If you're using Expo's location tools with Places Autocomplete, you can lock down your API key in Google Cloud Console: set app restrictions to only allow your Expo app's package name and SHA-1 fingerprint (use expo credentials:manager to get your app's fingerprint). Even if someone extracts the key, they can't use it for other apps.
  • Expo Application Services (EAS) Secrets
    Expo's EAS lets you store environment variables that are injected during app builds. Note: this still packages keys into your app—it's safer than hardcoding, but only suitable for low-sensitivity keys (like Google Places keys that have app restrictions). Never use this for high-risk secrets like SendGrid's secret key.

需要后端支持的完整安全方案(最稳妥)

For high-sensitivity secrets (like SendGrid's API key), a dedicated backend is the only truly secure option. Here's a simple Node.js + Express tutorial to get you started:

  1. Set up the backend project

    npm init -y
    npm install express cors dotenv @sendgrid/mail axios
    
  2. Create environment variables
    Make a .env file (add this to .gitignore so it never gets committed):

    SENDGRID_API_KEY=your-sendgrid-secret-key
    GOOGLE_PLACES_API_KEY=your-places-key
    PORT=3000
    
  3. Write the server code
    Create a server.js file:

    require('dotenv').config();
    const express = require('express');
    const cors = require('cors');
    const sgMail = require('@sendgrid/mail');
    const axios = require('axios');
    
    const app = express();
    app.use(cors());
    app.use(express.json());
    
    // Handle email requests
    app.post('/api/send-email', async (req, res) => {
      sgMail.setApiKey(process.env.SENDGRID_API_KEY);
      const { to, subject, text } = req.body;
      try {
        await sgMail.send({
          to,
          from: 'your-valid-sender-email@example.com',
          subject,
          text
        });
        res.status(200).send('Email sent successfully');
      } catch (error) {
        res.status(500).send(error.response?.data || error.message);
      }
    });
    
    // Handle Google Places requests
    app.get('/api/places', async (req, res) => {
      const { query } = req.query;
      try {
        const response = await axios.get('https://maps.googleapis.com/maps/api/place/autocomplete/json', {
          params: { input: query, key: process.env.GOOGLE_PLACES_API_KEY }
        });
        res.json(response.data);
      } catch (error) {
        res.status(500).send(error.response?.data || error.message);
      }
    });
    
    app.listen(process.env.PORT, () => {
      console.log(`Server running on port ${process.env.PORT}`);
    });
    
  4. Deploy the backend
    Host it on platforms like Render, Heroku, or DigitalOcean App Platform. When deploying, add your .env variables to the platform's environment settings (don't upload the .env file).

  5. Update frontend calls
    Instead of calling SendGrid/Google Places directly, call your backend endpoints:

    // Send email via backend
    const sendEmail = async (to, subject, text) => {
      const response = await fetch('https://your-backend-url/api/send-email', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ to, subject, text })
      });
      return response.ok;
    };
    
    // Get Places suggestions via backend
    const getPlaces = async (searchQuery) => {
      const response = await fetch(`https://your-backend-url/api/places?query=${encodeURIComponent(searchQuery)}`);
      return response.json();
    };
    

Final Takeaways

  • High-sensitivity secrets (SendGrid/Mailjet keys): Use serverless functions or a dedicated backend—never store them in the frontend.
  • Low-sensitivity keys (Google Places): Combine EAS Secrets with Google Cloud's app restrictions, or forward via backend for extra safety.
  • Skip any "frontend-only secure storage" claims: If it's in the app bundle, it can be extracted.

内容的提问来源于stack exchange,提问作者Ivo

火山引擎 最新活动