Security

Implementing Secure Authentication with Better Auth

A comprehensive guide to implementing secure, production-ready authentication using Better Auth in Next.js applications.

SutraCore Team · authorNovember 28, 202514 min read
#Authentication#Security#Better Auth#Next.js#OAuth

Authentication is critical for any application. Better Auth provides a modern, secure, and developer-friendly solution for Next.js applications.

Why Better Auth?

Better Auth offers several advantages:

  • Type-safe - Full TypeScript support
  • Flexible - Multiple authentication strategies
  • Secure - Built-in security best practices
  • Modern - Works with Next.js App Router
  • Extensible - Plugin system for custom features

Setup

Installation

npm install better-auth

Configuration

Create your auth configuration:

import { betterAuth } from 'better-auth'; import { drizzleAdapter } from 'better-auth/adapters/drizzle'; import { db } from './db'; export const auth = betterAuth({ database: drizzleAdapter(db), emailAndPassword: { enabled: true, requireEmailVerification: true, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, }, github: { clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, }, }, });

Authentication Flows

Email/Password Authentication

Implement secure email/password authentication:

// Sign up const { user, session } = await auth.signUp.email({ email: 'user@example.com', password: 'securePassword123', name: 'John Doe', }); // Sign in const { user, session } = await auth.signIn.email({ email: 'user@example.com', password: 'securePassword123', }); // Sign out await auth.signOut();

OAuth Authentication

Implement social login:

// Google OAuth const { url } = await auth.signIn.social({ provider: 'google', callbackURL: '/auth/callback', }); // Redirect user to OAuth provider redirect(url);

Email Verification

Send verification emails:

await auth.sendVerificationEmail({ email: 'user@example.com', callbackURL: '/verify-email', });

Session Management

Server-Side Session Handling

Protect API routes and server components:

import { auth } from '@/lib/auth'; import { headers } from 'next/headers'; export async function GET() { const session = await auth.api.getSession({ headers: await headers(), }); if (!session) { return new Response('Unauthorized', { status: 401 }); } return Response.json({ user: session.user }); }

Client-Side Session

Use the session in client components:

'use client'; import { useSession } from '@/lib/auth-client'; export function UserProfile() { const { data: session, isPending } = useSession(); if (isPending) return <Spinner />; if (!session) return <SignInButton />; return <div>Welcome, {session.user.name}!</div>; }

Security Best Practices

Password Requirements

Enforce strong passwords:

export const auth = betterAuth({ emailAndPassword: { enabled: true, minPasswordLength: 12, requireUppercase: true, requireLowercase: true, requireNumbers: true, requireSpecialChars: true, }, });

Rate Limiting

Protect against brute force attacks:

import { Ratelimit } from '@upstash/ratelimit'; import { Redis } from '@upstash/redis'; const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(5, '15 m'), }); export async function POST(request: Request) { const ip = request.headers.get('x-forwarded-for') ?? 'unknown'; const { success } = await ratelimit.limit(ip); if (!success) { return new Response('Too many requests', { status: 429 }); } // Process authentication }

CSRF Protection

Better Auth includes built-in CSRF protection:

export const auth = betterAuth({ advanced: { useSecureCookies: true, cookiePrefix: '__Secure-', generateSessionToken: () => { return crypto.randomUUID(); }, }, });

Multi-Factor Authentication

Add an extra layer of security:

// Enable TOTP await auth.twoFactor.enable({ userId: user.id, method: 'totp', }); // Verify TOTP const { success } = await auth.twoFactor.verify({ userId: user.id, code: '123456', });

Role-Based Access Control

Implement authorization:

export const auth = betterAuth({ plugins: [ { id: 'rbac', hooks: { after: [ { matcher: () => true, handler: async (context) => { // Add role to session if (context.session) { context.session.user.role = await getUserRole( context.session.user.id ); } }, }, ], }, }, ], });

Conclusion

Better Auth provides a comprehensive authentication solution with security built-in. By following these patterns, you can implement secure authentication that protects your users and your application.

Check out our SaaS boilerplate for a complete authentication implementation.

Share this article

Share on TwitterShare on LinkedIn