我正试图使用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”函数,该文件被认为是一个服务器组件。我该如何修复这个奇怪的错误?
1条答案
按热度按时间kdfy810k1#
它解决了:“+page.js”和“+layout.js”文件将呈现在服务器和客户端,因为当它呈现在浏览器上它抛出错误。为了解决这个问题,要在sveltekit服务器组件上使用纯node.js API,您必须使用“+page.server.js”或“+layout.server.js”文件。