I'm trying to create an authentication flow on svelte/sveltekit with using sveltekit api's and server side load function.
This is my "/" route:
<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>
this is my "/auth/logining" api route:
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 }
}));
};
When i take the positive response from that route, i redirect to the "/panel" route with a query parameter that contains jwt token that created.
This is the +page.js page of "/panel" route:
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
}
}
}
this is my +layout.svelte page:
<script>
export let data;
console.log("+layout.svelte page data: ", data);
</script>
<slot {data}></slot>
and this is +page.svelte file of "/panel" route/folder:
<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>
My server logs like that:
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
}
}
}
but my browser outputs like that and on page it only wrotes "500 internal error":
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
I don't have any idea why this error happens. I run the "decode" function of jsonwebtoken liblary on +page.js file, which is suppose to be a server component. And how can i fix this weird error?
It Solved: "+page.js" and "+layout.js" files will render both on server and client and because of that when it render on browser it throws error. For solving that, for using pure node.js api's on sveltekit server components you have to use "+page.server.js" or "+layout.server.js" files.