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