NodeJS Svelte TypeError:无法读取未定义的属性(阅读“from”),并且模块“buffer”已外部化以实现浏览器兼容性,错误

x6h2sr28  于 2023-10-17  发布在  Node.js
关注(0)|答案(1)|浏览(132)

我正试图使用sveltekit API和服务器端加载函数在svelte/sveltekit上创建一个身份验证流。
这是我的“/”路线:

<script>
    let statusMessage = "";

    function changeStatusMessage(message){
        statusMessage = message;
    };

    async function handleSubmit(param){
        param.preventDefault();

        let nicknameInput = document.querySelector("#nicknameInput");
        let passwordInput = document.querySelector("#passwordInput");

        console.log("nickname input value: ", nicknameInput.value);
        console.log("password input value: ", passwordInput.value);

        let request = await fetch("/auth/logining", {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({ nickname: nicknameInput.value, password: passwordInput.value })
        });

        let response = await request.json();

        console.log(response);

        if(!response.status){
            changeStatusMessage(response.message);
        } else {
            location.assign(`/panel?token=${response.body.token}`)
        };
    }

</script>

<h2 class="login-page-title">Necdetiye Ön Muhasebe Programına Hoş Geldiniz!</h2>

<main class="login-page">
    <form on:submit={handleSubmit}>
        <label for="nicknameInput">Kullanıcı Adı:</label>
        <input type="text" name="nickname" id="nicknameInput" placeholder="Kullanıcı Adınız">
        <label for="passwordInput">Şifre:</label>
        <input type="password" name="password" id="passwordInput" placeholder="Şifreniz">
        <input type="submit" value="Giriş Yap">
        <p>{statusMessage}</p>
    </form>
</main>

这是我的“/auth/logining”API路由:

import { redirect, json } from "@sveltejs/kit";
import { fetchDatasWithFiltering } from "../../../lib/firebase";
import { decrypt4 } from "necdetiye-crypto";
import { sign } from "jsonwebtoken";

export async function POST(context){
    console.log("our context object: ", context);

    let body = await context.request.json();

    console.log("our body object: ", body);

    let getUserObject = await fetchDatasWithFiltering("users", "nickname", "==", body.nickname);

    console.log("our user object: ", getUserObject);

    if(!getUserObject || getUserObject.length === 0 || getUserObject[0].nickname !== body.nickname){
        return json({ status: false, message: "Hata: Bu kullanıcı ismine sahip hiçbir kullanıcı yok." });
    };

    if(decrypt4(getUserObject[0].password, "asdfsdasfasdsfd") !== body.password){
        return json({ status: false, message: "Hata: Kullanıcı şifresi yanlış." });
    };

    let userObj = {
        nickname: getUserObject[0].nickname,
        email: getUserObject[0].email,
        role: getUserObject[0].role
    }

    let jwtToken = sign({ "nickname": userObj.nickname,
                          "email": userObj.email,
                          "role": userObj.role }, "kfnlksdfhvnkjhsdfkgjs", { expiresIn: "100 days" });

    return new Response(JSON.stringify({
        status: 200,
        headers: {
            "Content-Type": "application/json"
        },
        body: { message: "successfull authentication", token: jwtToken }
    }));
};

当我从该路由获得肯定响应时,我重定向到“/panel”路由,并使用包含创建的jwt token的查询参数。
这是“/panel”路由的+page.js页面:

import { redirect } from '@sveltejs/kit';
import { decode, verify } from 'jsonwebtoken';

/** @type {import('./$types').PageLoad} */
export function load({url, request, cookies}) {
    console.log("url object: ", url);
    console.log("our cookie: ", url.searchParams.get("token"))

    let ourToken = url.searchParams.get("token");

    if(!ourToken){
        throw redirect(303, "/?error=unauthorized");
    };

    let verifyToken = verify(ourToken, "kfnlksdfhvnkjhsdfkgjs");

    if(!verifyToken){
        throw redirect(303, "/?error=malformedtoken");
    };

    let user = decode(ourToken);

    console.log("/panel server side user obj: ", user);

    return {
        props: {
            data: user
        }
    }
}

这是我的+layout.svelte页面:

<script>
    export let data;

    console.log("+layout.svelte page data: ", data);
</script>

<slot {data}></slot>

这是“/panel”路由/文件夹的+page.svelte文件:

<script>
    import { setContext, hasContext, getContext } from 'svelte';

    export let data;

    console.log("+page.svelte page data obj: ", data);

    if(!hasContext("user")){
        setContext("user", data.props.data);
    }

    console.log("our context: ", getContext("user"));
</script>

我的服务器日志是这样的:

url object:  URL {
  href: 'http://localhost:5173/panel?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNrbmFtZSI6ImFkbWluIiwiZW1haWwiOiJpbGtlcm1vYmlseWExMDlAZ21haWwuY29tIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjk3Mzc0NDIxLCJleHAiOjE3MDYwMTQ0MjF9.PMYkl8Q9hGW9R1ztHFw8yeYdEsDmHTvyB-kNcGCrxW4',
  origin: 'http://localhost:5173',
  protocol: 'http:',
  username: '',
  password: '',
  host: 'localhost:5173',
  hostname: 'localhost',
  port: '5173',
  pathname: '/panel',
  search: '?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNrbmFtZSI6ImFkbWluIiwiZW1haWwiOiJpbGtlcm1vYmlseWExMDlAZ21haWwuY29tIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjk3Mzc0NDIxLCJleHAiOjE3MDYwMTQ0MjF9.PMYkl8Q9hGW9R1ztHFw8yeYdEsDmHTvyB-kNcGCrxW4',
  searchParams: URLSearchParams {
    'token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNrbmFtZSI6ImFkbWluIiwiZW1haWwiOiJpbGtlcm1vYmlseWExMDlAZ21haWwuY29tIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjk3Mzc0NDIxLCJleHAiOjE3MDYwMTQ0MjF9.PMYkl8Q9hGW9R1ztHFw8yeYdEsDmHTvyB-kNcGCrxW4' },
  hash: ''
}
our cookie:  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNrbmFtZSI6ImFkbWluIiwiZW1haWwiOiJpbGtlcm1vYmlseWExMDlAZ21haWwuY29tIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjk3Mzc0NDIxLCJleHAiOjE3MDYwMTQ0MjF9.PMYkl8Q9hGW9R1ztHFw8yeYdEsDmHTvyB-kNcGCrxW4
/panel server side user obj:  {
  nickname: 'admin',
  email: '[email protected]',
  role: 'admin',
  iat: 1697374421,
  exp: 1706014421
}
+layout.svelte page data:  {}
+page.svelte page data obj:  {
  props: {
    data: {
      nickname: 'admin',
      email: '[email protected]',
      role: 'admin',
      iat: 1697374421,
      exp: 1706014421
    }
  }
}

但我的浏览器输出像这样,在页面上它只写了“500内部错误”:

client.js?v=de4db00a:2083 Module "buffer" has been externalized for browser compatibility. Cannot access "buffer.Buffer" in client code. See http://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
warn    @   client.js?v=de4db00a:2083
get @   browser-external:buffer:9
node_modules/safe-buffer/index.js   @   index.js:4
__require   @   chunk-XNHBATJA.js?v=de4db00a:5
node_modules/jws/lib/sign-stream.js @   sign-stream.js:2
__require   @   chunk-XNHBATJA.js?v=de4db00a:5
node_modules/jws/index.js   @   index.js:2
__require   @   chunk-XNHBATJA.js?v=de4db00a:5
node_modules/jsonwebtoken/decode.js @   decode.js:1
__require   @   chunk-XNHBATJA.js?v=de4db00a:5
node_modules/jsonwebtoken/index.js  @   index.js:2
__require   @   chunk-XNHBATJA.js?v=de4db00a:5
(anonim)    @   index.js:8
client.js?v=de4db00a:2083 The next HMR update will cause the page to reload
warn    @   client.js?v=de4db00a:2083
handle_error    @   client.js?v=de4db00a:1328
_hydrate    @   client.js?v=de4db00a:1834
await in _hydrate (eş zamansız)     
start   @   start.js:22
(anonim)    @   panel?token=eyJhbGci…mHTvyB-kNcGCrxW4:28
Promise.then (eş zamansız)      
(anonim)    @   panel?token=eyJhbGci…mHTvyB-kNcGCrxW4:27
TypeError: Cannot read properties of undefined (reading 'from')
    at node_modules/safe-buffer/index.js (index.js:12:12)
    at __require (chunk-XNHBATJA.js?v=de4db00a:5:50)
    at node_modules/jws/lib/sign-stream.js (sign-stream.js:2:14)
    at __require (chunk-XNHBATJA.js?v=de4db00a:5:50)
    at node_modules/jws/index.js (index.js:2:18)
    at __require (chunk-XNHBATJA.js?v=de4db00a:5:50)
    at node_modules/jsonwebtoken/decode.js (decode.js:1:11)
    at __require (chunk-XNHBATJA.js?v=de4db00a:5:50)
    at node_modules/jsonwebtoken/index.js (index.js:2:11)
    at __require (chunk-XNHBATJA.js?v=de4db00a:5:50)
<Root> was created without expected prop 'form'
warn    @   client.js?v=de4db00a:2083
(anonim)    @   root.svelte:39
run @   utils.js:41
(anonim)    @   Component.js:47
flush   @   scheduler.js:99
init    @   Component.js:164
Root    @   root.svelte:21
createProxiedComponent  @   svelte-hooks.js?v=de4db00a:341
ProxyComponent  @   proxy.js?v=de4db00a:242
Proxy<Root> @   proxy.js?v=de4db00a:349
initialize  @   client.js?v=de4db00a:288
_hydrate    @   client.js?v=de4db00a:1840
await in _hydrate (eş zamansız)     
start   @   start.js:22
(anonim)    @   panel?token=eyJhbGci…mHTvyB-kNcGCrxW4:28
Promise.then (eş zamansız)      
(anonim)    @   panel?token=eyJhbGci…mHTvyB-kNcGCrxW4:27

我不知道为什么会出现这个错误。我在+page.js文件上运行jsonwebtoken库的“decode”函数,该文件被认为是一个服务器组件。我该如何修复这个奇怪的错误?

kdfy810k

kdfy810k1#

它解决了:“+page.js”和“+layout.js”文件将呈现在服务器和客户端,因为当它呈现在浏览器上它抛出错误。为了解决这个问题,要在sveltekit服务器组件上使用纯node.js API,您必须使用“+page.server.js”或“+layout.server.js”文件。

相关问题