Authentication

This project implements a secure authentication system using Auth.js v5 (formerly NextAuth.js), providing multiple authentication methods and a seamless user experience.

Key Features

🔐

Multiple Providers

Google OAuth, Magic Links

📧

Passwordless

Email magic links authentication

🛡️

Security

Rate limiting protection

🔄

Sessions

Robust session management

📱

Responsive

Mobile-friendly sign-in interface

Server-Side

Authentication helpers

Setup Guide

1. Environment Variables

Create or update your .env.local file:

# Auth.js configuration
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your_secret_key

# Google OAuth
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret

# Email (Resend)
RESEND_API_KEY=your_resend_api_key
RESEND_EMAIL=your_email@domain.com

2. Auth Configuration

Set up your authentication configuration in lib/auth.ts:

export const { auth, handlers, signIn, signOut } = NextAuth({
  adapter: DrizzleAdapter(db),
  providers: [
    Google({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    Email({
      from: process.env.RESEND_EMAIL,
      sendVerificationRequest: async ({ identifier, url }) => {
        await resend.emails.send({
          from: process.env.RESEND_EMAIL!,
          to: identifier,
          subject: "Sign in to Your App",
          react: MagicLinkEmail({ url }),
        })
      },
    }),
  ],
  // ... rest of configuration
})

Usage Examples

Protected API Routes

import { auth } from "@/lib/auth"

export async function GET() {
  const session = await auth()
  if (!session) {
    return new Response("Unauthorized", { status: 401 })
  }
  // Your protected API logic
}

Protected Pages

import { auth } from "@/lib/auth"

export default async function ProtectedPage() {
  const session = await auth()
  if (!session) {
    redirect("/sign-in")
  }
  return <div>Protected Content</div>
}

Getting Current User

import { getCurrentUser } from "@/server/actions/auth-actions"

const { user } = await getCurrentUser()
if (user) {
  // User is authenticated
  console.log(user.email)
}

Security Features

Rate Limiting

Protection against brute force attacks and abuse

const ratelimit = new Ratelimit({
  redis,
  limiter: Ratelimit.slidingWindow(5, "1 m"),
})

Type Safety

TypeScript definitions for better type safety

declare module "next-auth" {
  interface Session {
    user: UserType
  }
}

Best Practices

Environment Variables

  • Never commit sensitive credentials
  • Use different values for development and production
  • Regularly rotate secrets

Security

  • Keep dependencies updated
  • Implement proper CORS policies
  • Use HTTPS in production
  • Enable rate limiting

User Experience

  • Provide clear error messages
  • Implement proper loading states
  • Add remember me functionality
  • Support multiple auth methods

Additional Resources