Guides
Adding Authentication
Add a users collection with login, JWT auth, and protected routes.
1. Add an auth collection
// dyrected.config.ts (same for both frameworks)
export default defineConfig({
collections: [
{
slug: 'users',
auth: true,
fields: [
{ name: 'name', type: 'text' },
],
},
],
})2. Set the JWT secret
# .env.local
DYRECTED_JWT_SECRET=a-long-random-secret-at-least-32-charsThe same secret must be set in every environment. Rotating it invalidates all existing sessions.
3. Log in
import { createClient } from '@dyrected/sdk'
const client = createClient({ baseUrl: '/dyrected' })
const { token, user } = await client.collection('users').login(
'jane@example.com',
'hunter2'
)// app/login/actions.ts
'use server'
import { cookies } from 'next/headers'
import { createClient } from '@dyrected/sdk'
const client = createClient({ baseUrl: process.env.NEXT_PUBLIC_DYRECTED_URL! })
export async function login(email: string, password: string) {
const { token, user } = await client.collection('users').login(email, password)
cookies().set('dyrected-token', token, { httpOnly: true, path: '/' })
return user
}<!-- components/LoginForm.vue -->
<script setup lang="ts">
const { login, user, logout } = useDyrectedAuth('users')
async function submit(e: Event) {
const form = e.target as HTMLFormElement
await login(form.email.value, form.password.value)
}
</script>
<template>
<div v-if="user">
Hello, {{ user.name }} — <button @click="logout">Log out</button>
</div>
<form v-else @submit.prevent="submit">
<input name="email" type="email" placeholder="Email" />
<input name="password" type="password" placeholder="Password" />
<button type="submit">Log in</button>
</form>
</template>4. Protect API routes
// dyrected.config.ts — access functions work the same in both frameworks
{
slug: 'orders',
access: {
read: ({ user }) => !!user,
create: ({ user }) => !!user,
update: ({ user, doc }) => user?.id === doc.userId,
delete: ({ user }) => user?.role === 'admin',
},
}5. Protect frontend routes
// middleware.ts
import { NextRequest, NextResponse } from 'next/server'
export function middleware(req: NextRequest) {
const token = req.cookies.get('dyrected-token')?.value
if (!token) {
return NextResponse.redirect(new URL('/login', req.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/dashboard/:path*', '/account/:path*'],
}// middleware/auth.ts
export default defineNuxtRouteMiddleware(() => {
const { user } = useDyrectedAuth('users')
if (!user.value) return navigateTo('/login')
})Apply it to a page:
<!-- pages/dashboard.vue -->
<script setup>
definePageMeta({ middleware: 'auth' })
</script>6. Get the current user
// In a Server Component
import { cookies } from 'next/headers'
import { createClient } from '@dyrected/sdk'
const client = createClient({ baseUrl: process.env.NEXT_PUBLIC_DYRECTED_URL! })
async function getUser() {
const token = cookies().get('dyrected-token')?.value
if (!token) return null
client.setToken(token)
try {
return await client.collection('users').me()
} catch {
return null
}
}<script setup lang="ts">
const { user } = useDyrectedAuth('users')
// reactive — updates automatically on login/logout
</script>
<template>
<span v-if="user">{{ user.name }}</span>
</template>Next steps
- Invite-only registration — restrict sign-up to invited users
- Role-based access control — admin / editor / viewer roles
- Auth Endpoints — full REST API reference