【问题标题】:SvelteKit: How to call mongodb without using endpoints?SvelteKit:如何在不使用端点的情况下调用 mongodb?
【发布时间】:2022-01-02 04:13:41
【问题描述】:

我想调用我的数据库,但我不希望最终用户通过我设置的 API 端点访问它。我想知道如何才能从 lib 文件夹中的文件中调用我的数据库并在那里返回数据。当我尝试它时,我收到错误 global not defined:

lib/db.js:

import dotenv from "dotenv";
dotenv.config();
import { MongoClient } from "mongodb";

const uri = process.env["MONGODB_URI"];
const options = {
  useUnifiedTopology: true,
  useNewUrlParser: true,
};

let client;
let clientPromise;

if (!uri) {
  throw new Error("Please add your Mongo URI to .env.local");
}

if (process.env["NODE_ENV"] === "development") {
  if (!global._mongoClientPromise) {
    client = new MongoClient(uri, options);
    global._mongoClientPromise = client.connect();
  }
  clientPromise = global._mongoClientPromise;
} else {
  client = new MongoClient(uri, options);
  clientPromise = client.connect();
}
export default clientPromise;

路线/项目/index.js:

import clientPromise from "$lib/db";

export async function get() {
  const client = await clientPromise;
  const db = client.db();
  const data = await db.collection("items").find({}).toArray();
  const items = data.map(({ name }) => ({ name }));

  if (items) {
    return {
      body: {
        items,
      },
    };
  }
}

我的尝试: lib/stores/items.js

import clientPromise from "$lib/db";
import { writable } from "svelte/store";
export const items= writable([]);

const fetchItems = async () => {
  const client = await clientPromise;
  const db = client.db();
  const data = await db.collection("items").find({}).toArray();
  const items = data.map(({ name }) => ({ name }));

  substances.set(items);
};

fetchItems();

在不同的地方尝试上面的代码总是会在客户端产生global not defined 错误。

我从遇到相同问题的人那里找到了一个问题,但我不知道如何创建帮助文件。

【问题讨论】:

  • 只是好奇,你能解释一下为什么你不能使用端点吗?您是否正在尝试“保护”这些数据,例如免受抓取/机器人之类的攻击?你不能只返回你需要/想要渲染的数据吗?
  • @AlexanderStaroselsky 是的,差不多就是这样,我想学习如何保护 API,这样除了我的网站之外,没有人可以直接将其用作数据源。
  • 那么实现诸如oauth(cookies)之类的auth可能是值得的。话虽如此,您可以尝试检查端点中的请求对象,看看您是否可以确定请求是来自同一域上的加载函数还是来自外部源。如果可以区分,可以返回错误。
  • FWIW 我尝试了几种不同的方法,但没有得到我想要的。我一直遇到的问题是需要在某个地方设置到 MongoDB 的连接池。这可以在句柄钩子中有条件地完成,但是应用程序启动时的第一页加载会非常慢。从那里使用端点并不太困难,但响应时间很不稳定。我最终将 API 拆分到它自己的 Node 服务器中,并且只使用 sveltekit 进行路由和代码拆分,它运行良好。一旦 Sveltekit 获得了应用启动的钩子,而不仅仅是第一页加载,我可能会重新审视这个。

标签: javascript mongodb api svelte sveltekit


【解决方案1】:

保护 API 在后端完成。通常是服务器(如 NodeJS)或工具 Nginx/Apache(代理等)。您基本上是在寻找 Content-Security-Policy 主题,该主题很模糊但与 SvelteKit 无关。

顺便说一句,直接从前端调用 DB 不安全,也不可能。

【讨论】:

    【解决方案2】:

    要从任何数据库中获取数据,您应该创建enpoint

    对于用户认证,可以创建handle hook

    export async function handle({ request, resolve }) {
      let user = await authenticate(request) 
    
      request.locals.user = user
      request.locals.isAuthenticated = !!user
    
      if (request.path.startsWith('/api')) {
        if (!user) {
          return {
            status: 401,
            body: JSON.stringify({
              error: {
                message: 'Unauthorized'
              }
            })
          }
        }
    
      const response = await resolve(request)
      return response
    }
    

    【讨论】:

      猜你喜欢
      • 2021-05-26
      • 1970-01-01
      • 2021-11-07
      • 2015-10-17
      • 1970-01-01
      • 2015-08-22
      • 2019-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多