Authentication
Learn how to implement authentication in your Nuxt application using Nuxt Users.
Overview
The module provides a complete authentication system with:
- Secure login with bcrypt password hashing
- Token-based authentication (inspired by Laravel Sanctum)
- HTTP-only cookies for security
- Automatic token management
Whitelisting Routes
By default, all pages (except /login
) require authentication. You can whitelist routes that should be accessible without authentication using the auth.whitelist
option in your nuxt.config.ts
.
If you want to add other pages that can be accessed without authentication, like a /register
page, you can do so like this:
export default defineNuxtConfig({
modules: ['nuxt-users'],
nuxtUsers: {
auth: {
whitelist: ['/login', '/register'],
},
},
})
Authentication Flow
Upon successful login:
- User submits credentials - Email and password are sent to the server
- Password verification - The server verifies the password securely
- Token generation - A secure authentication token is created
- Cookie setting - An HTTP-only cookie is set in the browser
- Response - User data is returned to your application
Login API
Endpoint
POST /api/nuxt-users/session
Request Body
{
"email": "[email protected]",
"password": "password123"
}
Response
{
"user": {
"id": 1,
"email": "[email protected]",
"name": "John Doe",
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-01T00:00:00.000Z"
}
}
Error Responses
// 400 Bad Request
{
"statusMessage": "Email and password are required"
}
// 401 Unauthorized
{
"statusMessage": "Invalid email or password"
}
Using the NUsersLoginForm Component
The module provides a ready-to-use NUsersLoginForm
component:
<template>
<NUsersLoginForm
@success="handleSuccess"
@error="handleError"
/>
</template>
<script setup>
const handleSuccess = (user) => {
console.log('Login successful:', user)
// Redirect or update UI
await navigateTo('/dashboard')
}
const handleError = (error) => {
console.log('Login error:', error)
// Show error message to user
}
</script>
Custom Authentication
Manual Login
You can implement custom login logic:
<template>
<form @submit.prevent="handleLogin">
<input v-model="email" type="email" placeholder="Email" required />
<input v-model="password" type="password" placeholder="Password" required />
<button type="submit" :disabled="loading">
{{ loading ? 'Logging in...' : 'Login' }}
</button>
</form>
</template>
<script setup>
const email = ref('')
const password = ref('')
const loading = ref(false)
const handleLogin = async () => {
loading.value = true
try {
const response = await $fetch('/api/nuxt-users/session', {
method: 'POST',
body: {
email: email.value,
password: password.value
}
})
// Handle successful login
console.log('User:', response.user)
await navigateTo('/dashboard')
} catch (error) {
// Handle error
console.error('Login failed:', error)
// Show error message to user
} finally {
loading.value = false
}
}
</script>
For detailed usage of the useAuthentication
composable, refer to the Composables documentation.
Logout
The module provides a complete logout system that securely removes authentication tokens and clears user sessions.
Using the NUsersLogoutLink Component
The module provides a ready-to-use NUsersLogoutLink
component:
<template>
<NUsersLogoutLink
@success="handleSuccess"
@error="handleError"
/>
</template>
<script setup>
const handleSuccess = () => {
console.log('Logout successful')
// Handle successful logout
await navigateTo('/login')
}
const handleError = (error) => {
console.log('Logout error:', error)
// Show error message
}
</script>
Customizing the NUsersLogoutLink
You can customize the appearance and behavior:
<NUsersLogoutLink
link-text="Sign Out"
redirect-to="/home"
confirm-message="Are you sure you want to sign out?"
class="custom-logout-link"
/>
Manual Logout
For manual logout using the useAuthentication
composable, refer to the Composables documentation.
Direct API Call
You can also call the logout API directly:
<script setup>
const logout = async () => {
try {
await $fetch('/api/nuxt-users/session', { method: 'DELETE' })
console.log('Logged out successfully')
await navigateTo('/login')
} catch (error) {
console.error('Logout failed:', error)
}
}
</script>
Token Management
Configuring Token Expiration
Set token expiration time in your nuxt.config.ts
:
export default defineNuxtConfig({
modules: ['nuxt-users'],
nuxtUsers: {
auth: {
tokenExpiration: 1440, // 24 hours in minutes
}
}
})
The module automatically handles:
- Token expiration validation
- Automatic token cleanup
- Token refresh on activity
Security Features
Built-in Security
The authentication system includes several security features:
- Cryptographically secure tokens: Tokens are generated using secure random methods
- HTTP-only cookies: Prevents XSS attacks by making tokens inaccessible to JavaScript
- Automatic expiration: Tokens expire based on your configuration (default: 24 hours)
- Expired token cleanup: Automatic cleanup of expired tokens
- Token revocation: Ability to revoke all tokens for a user
Rate Limiting (Recommended)
For production deployments, we strongly recommend using nuxt-api-shield to protect authentication endpoints from brute force attacks:
# Install the rate limiting module
npx nuxi module add nuxt-api-shield
Configure rate limiting in your nuxt.config.ts
:
export default defineNuxtConfig({
modules: ['nuxt-users', 'nuxt-api-shield'],
nuxtUsers: {
// ... your nuxt-users config
},
apiShield: {
maxRequests: 5, // 5 login attempts per duration
duration: 60000, // 1 minute window
banDuration: 300000, // 5 minute ban for violators
delay: 1000, // 1 second delay on banned IPs
routes: [
'/api/nuxt-users/session', // Protect login endpoint
'/api/nuxt-users/password/forgot', // Protect password reset requests
'/api/nuxt-users/password/reset' // Protect password reset completion
],
log: true // Enable logging for monitoring
}
})
This configuration provides:
- Brute force protection: Limits login attempts per IP
- Automatic IP banning: Temporarily blocks malicious IPs
- Password reset protection: Prevents abuse of reset functionality
- Configurable thresholds: Adjustable for your security needs
- Monitoring: Logs for security analysis
Advanced Rate Limiting
For different security levels on different endpoints:
apiShield: {
routes: {
'/api/nuxt-users/session': {
maxRequests: 5, // Stricter limit for login
duration: 60000, // 1 minute
banDuration: 600000 // 10 minute ban
},
'/api/nuxt-users/password/forgot': {
maxRequests: 3, // Very strict for password reset
duration: 300000, // 5 minute window
banDuration: 1800000 // 30 minute ban
}
}
}
Checking Authentication Status
For checking authentication status using the useAuthentication
composable, refer to the Composables documentation.
Error Handling
For error handling with the useAuthentication
composable, refer to the Composables documentation.
Security Best Practices
- Use HTTPS: Always use HTTPS in production to protect credentials in transit
- Strong passwords: Enforce strong password policies for your users
- Rate limiting: Use nuxt-api-shield to protect authentication endpoints
- Token expiration: Set reasonable expiration times (default: 24 hours)
- Secure storage: Never store authentication tokens in localStorage or sessionStorage
- Input validation: Validate all user inputs on both client and server
- Error messages: Don't reveal too much information in error messages
- Monitoring: Monitor authentication attempts and failures
- Regular updates: Keep the module and dependencies updated
Next Steps
- Authorization (RBAC) - Learn about Role-Based Access Control
- Password Reset - Add password reset functionality
- Components - Learn about available Vue components
- Configuration - Explore all configuration options