Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I send secure API requests from SvelteKit app, without showing API keys on the client side?

I'm using Supabase for a new Sveltekit app, with this template

Currently, I'm passing the Supabase keys through on the client side, like this:

const supabase = createClient(
  import.meta.env.VITE_SUPABASE_URL,
  import.meta.env.VITE_SUPABASE_ANON_KEY
)

What is the simplest way that I can create a secure backend/API, so the application can fetch content from Supabase, without showing Supabase key on the client side?

Is there any functionality built into Sveltekit that enables me to do this? Or would I need to integrate a backend like Rails?

like image 335
amatur Avatar asked May 17 '21 10:05

amatur


People also ask

How do I protect API key from client side?

The only way to protect an API key is to keep the key only on the server. The client asks your server for some data and your server uses the API key to get the data from the API source and returns it back to the client. Anything you send to the client will be visible to any hacker.

Which is the most secure method to transfer an API key?

There is only one reliable way: use HTTPs for your web site to allow the users to retrieve the key. Then during the API calls HTTPS is no longer required. Your users can use HMAC authentication to hash the key with a shared secret.


1 Answers

SvelteKit supports server-side code in two main places:

  • endpoints
  • hooks

Code for these will never be accessible to the browser; only the results. Also any network calls made will not be visible to the client since they all happen on the server (for cases where API keys are embedded in the URL). The locals property of each API is a good place to share sensitive data (like API keys) with all the server-side parts.

The general recommendation is to proxy external API calls with local endpoints:

  1. Fetch a local SvelteKit endpoint from SvelteKit pages (instead of calling the external API, like Supabase, directly). You can fetch the endpoint from two different places on a page:
    • load() in <script context="module"> (allows calling API's from server-side before page is sent/rendered)
    • main <script>
  2. Initialize the external API in a singleton.
  3. Call the external API from the endpoint and return the results to the page.

Notes:

  • SvelteKit endpoints are a generalization of serverless lambda functions. (See Netlify or AWS flavors)
  • Any NPM modules used in endpoints/hooks must be devDependencies.
  • fetch() is recommended (vs axios, for example), especially within load(). load() provides a special version of fetch() that caches calls from the server-side so the client-side can reuse the results.
  • Step #2 is mainly to support serverless environments like Netlify.
like image 175
Leftium Avatar answered Oct 06 '22 00:10

Leftium