Mengimplementasikan autentikasi di ElysiaJS: setup JWT dengan plugin @elysiajs/jwt, cookie-based session management, bearer token pattern, dan guard pattern untuk melindungi route dari akses tidak sah.

Setelah di episode 11 kita mengamankan API dengan CORS, security headers, dan rate limiting, pada episode ini kita akan membangun lapisan autentikasi — mekanisme untuk memverifikasi identitas user sebelum mengakses resource yang dilindungi.
bun add @elysiajs/jwtimport { Elysia } from 'elysia'
import jwt from '@elysiajs/jwt'
const app = new Elysia()
.use(jwt({
name: 'jwt',
secret: process.env.JWT_SECRET,
}))
.listen(3000).post('/auth/login', async ({ jwt, body }) => {
const user = await authenticateUser(body.email, body.password)
if (!user) return { error: 'Invalid credentials' }
const token = await jwt.sign({
sub: user.id,
name: user.name,
exp: '7d',
})
return { token }
}, {
body: t.Object({
email: t.String({ format: 'email' }),
password: t.String(),
})
}).get('/profile', async ({ jwt, headers }) => {
const token = headers.authorization?.split(' ')[1]
if (!token) return { error: 'No token provided' }
const payload = await jwt.verify(token)
if (!payload) return { error: 'Invalid token' }
return { userId: payload.sub, name: payload.name }
}).post('/auth/login', async ({ jwt, cookie, body }) => {
const user = await authenticateUser(body.email, body.password)
if (!user) return { error: 'Invalid credentials' }
const token = await jwt.sign({ sub: user.id, exp: '7d' })
cookie.session.set(token, {
httpOnly: true,
secure: true,
sameSite: 'lax',
path: '/',
})
return { message: 'Logged in' }
}).get('/profile', async ({ jwt, cookie }) => {
const token = cookie.session.value
if (!token) return { error: 'Not authenticated' }
const payload = await jwt.verify(token)
if (!payload) return { error: 'Invalid session' }
return { userId: payload.sub }
})bun add @elysiajs/bearerimport bearer from '@elysiajs/bearer'
const app = new Elysia()
.use(bearer())
.get('/protected', async ({ bearer }) => {
if (!bearer) return { error: 'No bearer token' }
// verify bearer token
return { message: 'Access granted' }
})guard() memungkinkan kalian menerapkan auth ke grup routes secara bersamaan:
const checkAuth = async ({ jwt, headers }: any) => {
const token = headers.authorization?.split(' ')[1]
if (!token) throw new Error('Unauthorized')
const payload = await jwt.verify(token)
if (!payload) throw new Error('Invalid token')
return { userId: payload.sub }
}
const app = new Elysia()
.use(jwt({ name: 'jwt', secret: process.env.JWT_SECRET }))
.guard({ beforeHandle: checkAuth }, (app) =>
app
.get('/profile', ({ userId }) => ({ userId }))
.get('/settings', ({ userId }) => ({ userId }))
.post('/update', ({ userId, body }) => ({ userId, ...body }))
)app.derive(async ({ jwt, headers }) => {
const token = headers.authorization?.split(' ')[1]
const user = token ? await jwt.verify(token) : null
return { user }
})Tip
Gunakan derive() untuk menambahkan user ke context secara global, lalu guard() untuk apply auth ke grup routes. Kombinasi ini membuat autentikasi bersih dan mudah dirawat.
Pada episode 12 ini, kalian telah memahami autentikasi di ElysiaJS — dari JWT hingga cookie-based session dan guard pattern.
Inti yang harus dibawa pulang:
jwt.sign() dan jwt.verify() untuk token management.Di episode 13 selanjutnya kita akan memahami OAuth dan social login — integrasi GitHub OAuth dan Google OAuth untuk login tanpa password. Sampai jumpa di episode 13!