Authentication Layer
The authentication layer provides a flexible, plug-and-play authentication system for DCC-BS Nuxt applications. It enables switching between different authentication implementations (Azure AD, no-auth) using environment variables, without changing your application code.
Overview
The authentication system is designed with three layers:
auth- Base layer that defines the authentication interface and typesazure-auth- Production implementation using Microsoft Azure ADno-auth- Development/testing implementation that bypasses authentication
How It Works
The base auth layer dynamically loads an authentication implementation based on the AUTH_LAYER_URI environment variable. This allows you to:
- Switch from Azure AD to no-auth for local development
- Test without authentication dependencies
- Use different auth providers per environment (dev, staging, prod)
- Keep your application code authentication-agnostic
Architecture
Your Nuxt App
↓
extends: ['github:DCC-BS/nuxt-layers/auth']
↓
AUTH_LAYER_URI environment variable
↓
┌─────────────────┬─────────────────┐
↓ ↓ ↓
azure-auth no-auth (future: other-auth)Quick Start
1. Add Auth Layer to Your Project
In your nuxt.config.ts:
export default defineNuxtConfig({
extends: [
['github:DCC-BS/nuxt-layers/auth', { install: true }]
]
})2. Configure Authentication Implementation
Set the AUTH_LAYER_URI environment variable to choose your implementation:
For production (Azure AD):
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/azure-authFor development (no authentication):
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/no-auth3. Use Authentication in Your App
The auth layer provides type-safe authentication utilities:
// In a component or composable
const { data, signOut, isAuthEnabled } = useAppAuth();
// In server routes
export default authHandler.build('/api/protected-endpoint');Base Auth Layer (auth)
The base authentication layer defines the contract that all implementations must follow.
Type Definitions
User Type:
interface User {
name: string
email: string
// Additional user properties from auth provider
[key: string]: unknown
}AuthData Type:
interface AuthData {
user: User;
}Exports
- Types:
User,AuthData- Shared type definitions authHandler: Server utility for creating authenticated API handlers- Dynamic loading: Automatically extends the implementation specified in
AUTH_LAYER_URI
Configuration
The layer reads the following environment variable:
| Variable | Required | Description |
|---|---|---|
AUTH_LAYER_URI | Yes | URI to the authentication implementation layer |
Example:
# Use Azure AD authentication
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/azure-auth
# Use no authentication
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/no-auth
# Use local layer (for development)
AUTH_LAYER_URI=./layers/custom-authDocker Build-Time Configuration
The AUTH_LAYER_URI variable is resolved during nuxt build, meaning the authentication implementation is compiled into the application. When building Docker images, you must pass this value as a build argument (ARG), not a runtime environment variable.
# In your Dockerfile (after FROM, within the build stage)
ARG AUTH_LAYER_URIDocker injects ARG values into the shell environment during RUN commands, so nuxt build can read it via process.env. No ENV instruction needed — the value won't persist into the final image.
# When building
docker build --build-arg AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/azure-auth -t my-app .Related Documentation
For more details on Docker standards and best practices, see Internal Docker Standards.
Azure Auth Implementation (azure-auth)
Production-ready authentication using Microsoft Azure Active Directory (Azure AD / Entra ID).
Features
- ✅ OAuth 2.0 / OpenID Connect flow
- ✅ Automatic token refresh and management
- ✅ User profile integration with Azure AD
- ✅ Bearer token injection for backend API calls
- ✅ Secure session management
- ✅ Configuration validation on startup
Prerequisites
Before using Azure Auth, you need:
- An Azure AD application registration
- Configured redirect URIs in Azure portal
- Client ID and tenant ID from Azure
Configuration
Set these environment variables:
| Variable | Required | Description | Example |
|---|---|---|---|
AUTH_LAYER_URI | Yes | Points to azure-auth layer | github:DCC-BS/nuxt-layers/azure-auth |
NUXT_AZURE_AUTH_CLIENT_ID | Yes | Azure AD application client ID | 12345678-1234-... |
NUXT_AZURE_AUTH_TENANT_ID | Yes | Azure AD tenant ID | 87654321-4321-... |
NUXT_AZURE_AUTH_CLIENT_SECRET | Yes | Azure AD client secret | abc123... |
NUXT_AZURE_AUTH_API_CLIENT_ID | Yes | Azure AD API Client ID (for backend access) | 12345678-1234-... |
NUXT_AZURE_AUTH_SECRET | Yes | Secret for encrypting session tokens | a-long-random-string |
NUXT_AZURE_AUTH_ORIGIN | Yes | Base URL of the application (used for redirects) | https://app.example.com |
API_URL | Yes | Backend API base URL | https://api.example.com |
Azure AD Setup
Create an App Registration in Azure Portal:
- Go to Azure Active Directory → App registrations
- Click "New registration"
- Set a name for your application
- Choose "Accounts in this organizational directory only"
Configure Authentication:
- Add platform: Web
- Add redirect URI:
https://your-app.com/auth/callback - Enable ID tokens and access tokens
Note the Application Details:
- Copy the "Application (client) ID" →
NUXT_AZURE_AUTH_CLIENT_ID - Copy the "Directory (tenant) ID" →
NUXT_AZURE_AUTH_TENANT_ID - Create a client secret →
NUXT_AZURE_AUTH_CLIENT_SECRET - Copy the "Application (client) ID" of the backend API →
NUXT_AZURE_AUTH_API_CLIENT_ID
- Copy the "Application (client) ID" →
Configure API Permissions (if accessing Azure APIs):
- Add required Microsoft Graph permissions
- Grant admin consent if required
How It Works
- User visits protected route → Redirected to Azure AD login
- User authenticates → Azure AD redirects back with authorization code
- Token exchange → Backend exchanges code for access & ID tokens
- Session created → User info stored in session
- API calls →
authHandlerautomatically adds Bearer token to requests
Using authHandler
The authHandler provided by azure-auth automatically includes the Azure AD access token in backend API requests:
// server/api/users/index.get.ts
export default authHandler.build('/users')This handler will:
- Extract the user's access token from their session
- Add
Authorization: Bearer <token>header to the backend request - Forward the request to
${API_URL}/users - Return the response to the client
Custom Handler with Azure Auth
You can extend the authHandler for custom logic:
INFO
see also Backend Communication
// server/api/custom.post.ts
export default authHandler
.withMethod('POST')
.postMap(async (response) => {
// Transform response
return {
data: response,
processedAt: new Date().toISOString()
}
})
.build('/api/custom-endpoint')User Composable
Access the authenticated user in your Vue components:
<script setup>
const { data } = useAppAuth();
</script>
<template>
<div v-if="data">
<p>Welcome, {{ data.user.name }}!</p>
<p>Email: {{ data.user.email }}</p>
</div>
<div v-else>
<p>Please log in</p>
</div>
</template>Security Considerations
- Tokens are stored securely in server-side sessions
- Access tokens are never exposed to the client
- Token refresh is handled automatically
- HTTPS is required for production deployments
No Auth Implementation (no-auth)
A stub implementation that bypasses authentication, useful for development and testing.
Features
- ✅ No authentication required
- ✅ Mock user data for testing
- ✅ Simple
authHandlerwithout auth headers - ✅ Perfect for local development
When to Use
Use no-auth when:
- 🛠️ Developing locally without Azure AD access
- 🧪 Running automated tests that don't need real authentication
- 📄 Building public-facing pages that don't require login
- 🐛 Debugging application logic without auth complexity
Configuration
Simply set the environment variable:
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/no-authNo additional configuration is needed. The API_URL is still required for backend communication.
How It Works
The no-auth layer:
- Skips authentication checks - All requests are treated as authenticated
- Provides empty user - Returns a user object whete all fields are empty strings
- useAppAuth().isAuthEnabled returns false - Indicates no authentication is active
- Simple authHandler - Forwards requests without authentication headers
- No token management - No OAuth flow or token refresh
Mock User Data
The no-auth implementation provides a empty user:
{
name: "",
email: "",
image: "",
}Check if authentication is enabled:
<script setup lang="ts">
const { data, isAuthEnabled } = useAppAuth();
</script>
<template>
<div v-if="isAuthEnabled">
<p>Authenticated User: {{ data.user.name }}</p>
</div>
</template>Using authHandler (No Auth)
The authHandler in no-auth mode works the same way, but doesn't add authentication headers:
// server/api/data.get.ts
export default authHandler.build('/data')This forwards requests to the backend without the Authorization header. Your backend should be configured to accept unauthenticated requests in development mode.
Development Workflow
A typical development setup:
# .env.development
API_URL=http://localhost:8000
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/no-auth# .env.production
API_URL=https://api.example.com
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/azure-auth
NUXT_AZURE_AUTH_CLIENT_ID=...
NUXT_AZURE_AUTH_TENANT_ID=...
NUXT_AZURE_AUTH_CLIENT_SECRET=...
NUXT_AZURE_AUTH_API_CLIENT_ID=...
NUXT_AZURE_AUTH_SECRET=...
NUXT_AZURE_AUTH_ORIGIN=https://app.example.comLimitations
- ⚠️ Backend must allow unauthenticated requests - Or you'll get 401 errors
Switching Between Implementations
The power of this layer system is seamless switching:
Per Environment
Use different .env files:
# .env.local
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/no-auth
# .env.production
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/azure-authPer Developer
Each developer can use their own .env.local:
# Alice's .env.local (has Azure access)
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/azure-auth
NUXT_AZURE_AUTH_CLIENT_ID=...
# Bob's .env.local (no Azure access)
AUTH_LAYER_URI=github:DCC-BS/nuxt-layers/no-authAdvanced Usage
Creating Custom Auth Implementations
Create a layer
bun create nuxt -- --template layer nuxt-layerEdit .nuxt.config.ts
export default defineNuxtConfig({
extends: [
['github:DCC-BS/nuxt-layers/auth', { install: true }]
],
devtools: { enabled: true },
});run
bun i
bun dev:prepareRemove the generate code in the app/ directory and implement your own authentication logic:
add app/composables/useAuth.ts
import type { AuthData } from "#layers/auth/app/types/authData";
import type { UseAppAuthReturns } from "#layers/auth/app/types/composableTypes";
export function useAppAuth(): UseAppAuthReturns {
const data = computed<AuthData>(() => {
return {
user: {
image: // your Implementation,
name: // your Implementation,
email: // your Implementation,
},
};
});
async function signOut(): Promise<void> {
// your Implementation
}
async function signIn(): Promise<void> {
// your Implementation
}
return {
signIn,
signOut,
data,
isAuthEnabled: computed(() => !!nuxtData.value),
};
}add server/utils/authHandler.ts
export const authHandler = backendHandlerBuilder().extendFetchOptions(
async (options) => {
// your Implementation to get auth context
const { apiAccessToken } = await getAuthContext(options.event);
return {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${apiAccessToken}`,
},
};
},
);implement middlewares, endpoints, etc. as needed.
Example structure:
my-custom-auth/
├── .playground/
│ └──nuxt.config.ts
├── app/
│ └── composables/
│ └── useAppAuth.ts
├── server/
│ └── utils/
│ └── authHandler.ts
├── package.json
├── ...
└── nuxt.config.tsNow you can use your custom auth layer by setting the environment variable in a nuxt application whch uses the Auth layer:
AUTH_LAYER_URI=github:your-github-username/your-custom-authRelated Documentation
- Backend Communication Layer - Used by auth implementations
- Health Check Layer - Monitoring endpoints
- Nuxt Layers Overview - Main documentation
