Authentication
Authentication guide
Authentication
Auth is done with better-auth, a comprehensive authentication library.
Why better-auth?
better-auth can be used in basically any environment thanks to its flexibility. It can be integrated with backend, frontend and database very easily. It also comes with a lot of useful features like email or phone verification, password reset, Captcha, social sign-in like Google, Facebook, GitHub, and more.
How to use it in vth?
In other to use better-auth properly you have to integrate it with backend and frontend.
Server-side
Server-side logic is stored in lib/auth.ts, it's integrated with SQLite database and can be used in API routes. This setup includes a simple email and password authentication:
import { betterAuth } from 'better-auth';
import { db } from '@/lib/database';
export const auth = betterAuth({
database: { db },
emailAndPassword: {
enabled: true,
},
});Now you can implement routes for Hono:
/** @jsxImportSource hono/jsx */
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { serveStatic } from '@hono/node-server/serve-static';
import { auth } from '@/lib/auth';
const app = new Hono<{
Variables: {
user: typeof auth.$Infer.Session.user | null;
session: typeof auth.$Infer.Session.session | null;
};
}>();
app.use('*', async (c, next) => {
const session = await auth.api.getSession({ headers: c.req.raw.headers });
if (!session) {
c.set('user', null);
c.set('session', null);
return next();
}
c.set('user', session.user);
c.set('session', session.session);
return next();
});
app.use(
'/api/auth/*',
cors({
origin: process.env.BETTER_AUTH_URL,
allowHeaders: ['Content-Type', 'Authorization'],
allowMethods: ['POST', 'GET', 'OPTIONS'],
exposeHeaders: ['Content-Length'],
maxAge: 600,
credentials: true,
}),
);
app.on(['POST', 'GET'], '/api/auth/**', (c) => auth.handler(c.req.raw));
// ...Now to access the authenticated user you can use c.get('user') in API route:
app.get('/api/secret', async (c) => {
const user = c.get('user');
if (!user) {
return c.json({ message: 'Not authenticated' }, 401);
}
return c.json({ message: `Hello ${user.email}` });
});Client-side
Client-side logic is stored in /lib/auth-client.ts:
import { createAuthClient } from 'better-auth/react';
export const authClient = createAuthClient();
export const { useSession } = authClient;Now you can use it in your components:
import { authClient } from '@/lib/auth-client';
await authClient.signIn.email({
email,
password,
callbackURL: '/dashboard',
}, {
onError: (error) => {
// handle error
},
});To get the user data you can use useSession in your components:
import { useSession } from '@/lib/auth-client';
const { data: session, isPending, error, refetch } = useSession();Learn more
See docs to learn more.