如何在 sveltekit 1.0 上保护 api 密钥

问题描述 投票:0回答:4

我正在使用 Ghost,我做了一个集成,我想从前端隐藏 api 密钥。我不相信我可以对 Ghost cms 设置限制(这也可以)。我确实相信 +page.js 文件也在浏览器上运行,所以我对如何实现这一点有点困惑?

security sveltekit ghost-blog
4个回答
7
投票

内部 sveltekit 模块

$env/static/private
(docs) 是您使用安全 API 密钥的方式。 Sveltekit 不允许您将此模块导入到客户端代码中,因此它提供了额外的安全层。 Vite 在构建时自动从
.env
文件和
process.env
加载您的环境变量,并将您的密钥注入到服务器端包中。

import { API_KEY } from '$env/static/private';
// Use your secret

Sveltekit 有 4 个用于访问环境变量的模块

  • $env/static/private
    (覆盖)
  • $env/static/public
    可由服务器和客户端访问并在构建时注入(docs
  • $env/dynamic/private
    由您的运行时适配器提供;只包含以 do not 开头的变量,默认为
    PUBLIC_
    并且只能由服务器文件导入 (docs)
  • $env/dynamic/public
    由您的运行时适配器提供;仅包含以 do 开头的变量,默认为
    PUBLIC_
    (docs)

4
投票

在公众视野中隐藏第三方 API 密钥的一种常见方法是设置代理 API 路由。

总体思路是让您的客户端(浏览器)查询您提供/托管的代理 API 路由,让该代理路由使用您的凭据(API 密钥)查询第三方 API,并传递第三方的结果 -方 API 返回给客户端。

由于对第三方 API 的查询仅在后端进行,因此您的凭据永远不会暴露给客户端(浏览器),因此对公众不可见。

在您的用例中,您必须创建 3 个动态端点路由来复制 Ghost 的 API 结构:

src/routes/api/[resource]/+server.js
匹配
/posts/
/authors/
/tags/
等:

const API_KEY = <your_api_key>; // preferably pulled from ENV
const GHOST_URL = `https://<your_ghost_admin_domain>/ghost/api/content`;

export function GET({ params, url }) {
    const { resource } = params;
    const queryString = url.searchParams.toString();

    return fetch(`${GHOST_URL}/${resource}/?key=${API_KEY}${queryString ? `&${queryString}` : ''}`, {
        headers: {
            'Accept-Version': '5.0' // Ghost API Version setting
        }
    });
}

src/routes/api/[resource]/[id]/+server.js
匹配
/posts/{id}/
/authors/{id}/
等:

const API_KEY = <your_api_key>; // preferably pulled from ENV
const GHOST_URL = `https://<your_ghost_admin_domain>/ghost/api/content`;

export function GET({ params, url }) {
    const { resource, id } = params;
    const queryString = url.searchParams.toString();

    return fetch(`${GHOST_URL}/${resource}/${id}/?key=${API_KEY}${queryString ? `&${queryString}` : ''}`, {
        headers: {
            'Accept-Version': '5.0' // Ghost API Version setting
        }
    });
}

src/routes/api/[resource]/slug/[slug]/+server.js
匹配
/posts/slug/{slug}/
/authors/slug/{slug}/
等:

const API_KEY = <your_api_key>; // preferably pulled from ENV
const GHOST_URL = `https://<your_ghost_admin_domain>/ghost/api/content`;

export function GET({ params, url }) {
    const { resource, slug } = params;
    const queryString = url.searchParams.toString();

    return fetch(`${GHOST_URL}/${resource}/slug/${slug}/?key=${API_KEY}${queryString ? `&${queryString}` : ''}`, {
        headers: {
            'Accept-Version': '5.0' // Ghost API Version setting
        }
    });
}

然后您所要做的就是在应用程序中调用代理路由来代替原始第三方 API 路由:

// very barebones example
<script>
    let uri;
    let data;

    async function get() {
        const res = await fetch(`/api/${uri}`);
        data = await res.json();
    }
</script>

<input name="uri" bind:value={uri} />
<button on:click={get}>GET</button>
{data}

请注意,使用代理 API 路由还具有回避潜在 CORS 问题的额外好处。


1
投票

您无需隐藏密钥。

Ghost Content API 文档:

这些密钥可以安全地在浏览器和其他不安全的环境中使用,因为它们只提供对公共数据的访问。


0
投票

在 SvelteKit 目录根目录下的 .env 文件中,您可以在键名称前添加 VITE_ 前缀,例如 VITE_GHOST_CONTENT_API_KEY。

    //.env
     VITE_GHOST_CONTENT_API_KEY=[YOUR_API_KEY]

这样你就可以像这样导入它们:

//+page.server.ts
...
const API_KEY = import.meta.env.VITE_GHOST_CONTENT_API_KEY
...
© www.soinside.com 2019 - 2024. All rights reserved.