my-sveltekit-auth/
├── src/
│ ├── lib/
│ │ ├── server/
│ │ │ ├── db.ts # MongoDB connection
│ │ │ └── auth.ts # Auth utilities
│ │ └── components/
│ │ └── AuthForm.svelte
│ ├── routes/
│ │ ├── login/
│ │ │ └── +page.svelte
│ │ ├── register/
│ │ │ └── +page.svelte
│ │ ├── dashboard/
│ │ │ └── +page.svelte
│ │ └── +layout.svelte
│ └── hooks.server.ts
├── .env
└── package.json
npm create svelte@latest my-sveltekit-auth
cd my-sveltekit-auth
npm install mongodb bcryptjs jsonwebtoken dotenv
npm install --save-dev @types/bcryptjs @types/jsonwebtoken
MONGODB_URI = mongodb://<username>:<password>@###
DB_NAME = Database name
JWT_SECRET = Generate JWT
JWT_EXPIRES_IN= "7d"
របៀប copy URL database ពី MongoDB Atlas មកដាក់ .env ដោយយើងធ្វើដូចខាងក្រោម:
-> ចំណុច project click យក View all Projects -> click យក database ណាមួយដែលត្រូវប្រើ -> នៅខាងក្រោមផ្ទាំង Clusters មានផ្ទាំងមួយឈ្មោះថា Application Development -> Connect new -> copy url ។
1.) lib/server/db.ts
បង្កើត Database Connection
import { MongoClient } from "mongodb";
import {MONGODB_URL, DB_NAME} from '$env/static/private'
const client = new MongoClient(MONGODB_URL)
export async function connectToDatabase() {
try {
await client.connect()
console.log("Success Connected!")
return client.db(DB_NAME)
} catch (error) {
console.error("Mongodb connection error: ", error)
throw error
}
}
export const db = client.db(DB_NAME)
2.) lib/server/auth.ts
បង្កើត Auth Utilities
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { JWT_SECRET, JWT_EXPIRES_IN } from '$env/static/private';
import type { Db, ObjectId } from 'mongodb';
export interface User {
_id?: ObjectId;
email: string;
password: string;
name: string;
createdAt: Date;
updatedAt: Date;
}
export interface JWTPayload {
userId: string;
email: string;
name: string;
}
// បង្កើតអ្នកប្រើប្រាស់ថ្មី
export async function createUser(db: Db, email: string, password: string, name: string) {
// ពិនិត្យមើលថាអ៊ីមែលមានរួចហើយឬនៅ
const existingUser = await db.collection('users').findOne({ email });
if (existingUser) {
throw new Error('អ៊ីមែលនេះមានរួចហើយ');
}
// ធ្វើ Hashing ពាក្យសម្ងាត់
const hashedPassword = await bcrypt.hash(password, 10);
const user = {
email,
password: hashedPassword,
name,
createdAt: new Date(),
updatedAt: new Date()
};
const result = await db.collection('users').insertOne(user);
return { ...user, _id: result.insertedId };
}
// ផ្ទៀងផ្ទាត់ពាក្យសម្ងាត់ពេល Login
export async function verifyUser(db: Db, email: string, password: string) {
const user = await db.collection('users').findOne({ email });
if (!user) {
return null;
}
const isValid = await bcrypt.compare(password, user.password);
if (!isValid) {
return null;
}
return user;
}
// បង្កើត JWT Token
export function generateToken(user: any): string {
const payload: JWTPayload = {
userId: user._id.toString(),
email: user.email,
name: user.name
};
return jwt.sign(payload, JWT_SECRET, {
expiresIn: JWT_EXPIRES_IN
});
}
// ផ្ទៀងផ្ទាត់ JWT Token
export function verifyToken(token: string): JWTPayload | null {
try {
return jwt.verify(token, JWT_SECRET) as JWTPayload;
} catch (error) {
return null;
}
}
3.) src/hooks.server.ts
ការកំណត់ Hooks សម្រាប់ Authentication
import { connectToDatabase } from '$lib/server/db';
import { verifyToken } from '$lib/server/auth';
import { redirect, type Handle } from '@sveltejs/kit';
export const handle: Handle = async ({ event, resolve }) => {
// ភ្ជាប់ទៅ MongoDB
const db = await connectToDatabase();
event.locals.db = db
// ពិនិត្យមើល Token ពី Cookie
const token = event.cookies.get('auth-token');
if (token) {
const user = verifyToken(token);
if (user) {
event.locals.user = user;
} else {
// បើ Token មិនត្រឹមត្រូវ លុប Cookie ចោល
event.cookies.delete('auth-token', { path: '/' });
}
}
// ការពារ Route ដែលត្រូវការ Login
if (event.url.pathname.startsWith('/dashboard')) {
if (!event.locals.user) {
throw redirect(303, '/login');
}
}
// បើអ្នកប្រើបាន Login រួចហើយ មិនអាចចូលទំព័រ Login/Register ទៀតទេ
if ((event.url.pathname === '/login' || event.url.pathname === '/register') && event.locals.user) {
throw redirect(303, '/dashboard');
}
return resolve(event);
};
4.) lib/components/AuthForm.svelte
បង្កើត Login/Register Form Component
<script lang="ts">
let { form = null, type = 'login' } = $props();
console.log(type)
</script>
<form method="POST" class="auth-form">
{#if type === 'register'}
<div class="form-group">
<label for="name">ឈ្មោះពេញ</label>
<input
type="text"
id="name"
name="name"
value={form?.name || ''}
required
/>
</div>
{/if}
<div class="form-group">
<label for="email">អ៊ីមែល</label>
<input
type="email"
id="email"
name="email"
value={form?.email || ''}
required
/>
</div>
<div class="form-group">
<label for="password">ពាក្យសម្ងាត់</label>
<input
type="password"
id="password"
name="password"
required
/>
</div>
{#if type === 'register'}
<div class="form-group">
<label for="confirmPassword">បញ្ជាក់ពាក្យសម្ងាត់</label>
<input
type="password"
id="confirmPassword"
name="confirmPassword"
required
/>
</div>
{/if}
{#if form?.error}
<div class="error-message">
{form.error}
</div>
{/if}
<button type="submit" class="submit-btn">
{type === 'login' ? 'ចូលប្រើ' : 'ចុះឈ្មោះ'}
</button>
</form>
5.) routes/resister/
6.) routes/login/
npm install -D @sveltejs/adapter-netlify
កែប្រែ svelte.config.js៖
import adapter from '@sveltejs/adapter-netlify';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
adapter: adapter({
// បើចង់ប្រើ Edge Functions (សម្រាប់ប្រតិកម្មលឿន)
edge: false,
// បើចង់ប្រើ Serverless Functions
split: false,
// ទំហំ function (ស្រេចចិត្ត)
// functionMemorySize: 1024,
})
}
};
export default config;
បង្កើតឯកសារ netlify.toml នៅ root នៃគម្រោង៖
[build]
command = "npm run build"
publish = "build"
[build.environment]
NODE_VERSION = "20"
# កំណត់ Functions directory
[functions]
node_bundler = "esbuild"
# កំណត់ Redirects (សម្រាប់ SPA mode)
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
ពិនិត្យមើល package.json ថាមាន scripts ទាំងនេះ៖
{
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
}
}
ជំហានទី 5: សាកល្បង Build មូលដ្ឋាន
# សាកល្បង build មើល
npm run build
# បើ build ជោគជ័យ នឹងឃើញ folder build/
ls build