Overview

Learn how to authenticate users using the starter kit.

Nuxt Starter Kit uses better-auth to provide a modern, type-safe authentication system. The authentication code is located in the packages/layer-auth directory and handles login, logout, session management, and more.

Supported Authentication Methods

  • Email and password
  • Social login (Google & GitHub)

Better-auth Features

  • Type-safe - Full TypeScript support
  • Session management - Secure session handling
  • Social providers - Easy OAuth integration
  • Database-backed - Sessions stored in PostgreSQL
  • Extensible - Plugin system for custom features

Environment Variables

Required in .env:

# Better-auth configuration
BETTER_AUTH_SECRET=your-secret-key-min-32-chars
BETTER_AUTH_URL=http://localhost:9009

# Social login (optional)
NUXT_OAUTH_GITHUB_CLIENT_ID=your-github-client-id
NUXT_OAUTH_GITHUB_CLIENT_SECRET=your-github-client-secret

NUXT_OAUTH_GOOGLE_CLIENT_ID=your-google-client-id
NUXT_OAUTH_GOOGLE_CLIENT_SECRET=your-google-client-secret

Client-side Usage

Use the useAuth() composable (auto-imported):

<script setup lang="ts">
const { client, session, user } = useAuth()

async function signIn () {
  await client.signIn.email({
    email: '[email protected]',
    password: 'password'
  })
}

async function signOut () {
  await client.signOut()
}
</script>

<template>
  <div v-if="user">
    <p>Welcome {{ user.name }}!</p>
    <button @click="signOut">
      Sign out
    </button>
  </div>
  <div v-else>
    <button @click="signIn">
      Sign in
    </button>
  </div>
</template>

Server-side Usage

Require Authentication

Use requireAuth() to ensure a user is authenticated:

// server/api/protected.get.ts
export default defineEventHandler(async (event) => {
  const { session, user } = await requireAuth(event)

  // User is guaranteed to be authenticated here
  return { message: `Hello ${user.name}!` }
})

Optional Authentication

Use useServerAuth() when authentication is optional:

// server/api/optional.get.ts
export default defineEventHandler(async (event) => {
  const { session, user } = await useServerAuth(event)

  if (user) {
    return { message: `Hello ${user.name}!` }
  }

  return { message: 'Hello guest!' }
})

Database Schema

Better-auth uses these tables (in packages/layer-auth/server/db/schema/auth.ts):

  • user - User accounts
  • session - Active sessions
  • account - OAuth provider accounts
  • verification - Email verification tokens

Plugins

The starter kit includes:

Polar Plugin

Integrates with Polar.sh for payments:

import { polar } from '@polar-sh/better-auth'

// Already configured in layer-auth

Social Login Setup

GitHub OAuth

  1. Go to GitHub Settings > Developer settings > OAuth Apps
  2. Create a new OAuth App
  3. Set Authorization callback URL to: https://your-domain.com/api/auth/callback/github
  4. Copy Client ID and Client Secret to .env

Google OAuth

  1. Go to Google Cloud Console
  2. Create a new project or select existing
  3. Enable Google+ API
  4. Create OAuth 2.0 credentials
  5. Add authorized redirect URI: https://your-domain.com/api/auth/callback/google
  6. Copy Client ID and Client Secret to .env

Customization

Authentication is configured in packages/layer-auth/server/utils/auth.ts. You can:

  • Add more OAuth providers
  • Configure session duration
  • Add custom plugins
  • Modify user schema

Security

Better-auth provides:

  • Secure session storage
  • CSRF protection
  • Rate limiting (when configured)
  • Password hashing with bcrypt
  • Secure cookie handling