Overview
The Authentication Actions module provides server-side functions for handling user authentication with a Laravel Sanctum backend. It manages secure token storage using HTTP-only cookies.
The current implementation includes hardcoded credentials for development/testing purposes. This should be replaced with proper authentication flows in production.
loginSilent
Performs an automatic login using predefined credentials. Retrieves a Sanctum authentication token and stores it in an HTTP-only cookie.
export async function loginSilent () : Promise < string | null >
Response
Returns the authentication token on success, or null on failure
Features
HTTP-Only Cookies : Stores token securely, inaccessible to JavaScript
TLS Bypass : Disables certificate validation in development for self-signed certificates
Automatic Configuration : Reads backend URL from environment variables
Session Management : Configures cookie with 7-day expiration
Cookie Configuration
Property Value Description Name auth_tokenCookie name HttpOnly truePrevents XSS access Secure true (production)HTTPS-only in production SameSite laxCSRF protection Path /Available site-wide MaxAge 604800 seconds 7 days
Example
const token = await loginSilent ();
if ( token ) {
console . log ( '[Auth] Login successful' );
// Token is automatically stored in cookie
// Subsequent requests will include auth_token
} else {
console . error ( '[Auth] Login failed' );
}
API Endpoint
Makes a POST request to:
{NEXT_PUBLIC_BACKEND_API_URL}/api/autenticacion/iniciar-sesion
Request Body
{
"email" : "tecnico@test.com" ,
"password" : "12345678"
}
Expected Backend Response
{
"estado" : "exito" ,
"data" : {
"token" : "1|abcdefghijklmnopqrstuvwxyz1234567890"
}
}
getAuthToken
Retrieves the stored authentication token from cookies.
export async function getAuthToken () : Promise < string | undefined >
Response
Returns the token value if present, or undefined if not found
Example
const token = await getAuthToken ();
if ( token ) {
// Use token for authenticated requests
const response = await fetch ( ` ${ backendUrl } /api/protected-route` , {
headers: {
'Authorization' : `Bearer ${ token } `
}
});
} else {
// User not authenticated, redirect to login
console . log ( 'No auth token found' );
}
Use Cases
API Requests : Include token in Authorization headers
Session Validation : Check if user is authenticated
Middleware : Verify authentication in Next.js middleware
Server Components : Access auth state in React Server Components
Configuration
Environment Variables
NEXT_PUBLIC_BACKEND_API_URL
string
default: "https://gima-backend.test"
Base URL of the Laravel backend API
Node environment. When set to development, disables TLS certificate validation
Development Mode
In development (NODE_ENV === 'development'), the module automatically:
Disables TLS certificate validation (NODE_TLS_REJECT_UNAUTHORIZED = '0')
Sets secure: false on cookies for HTTP testing
Enables verbose console logging
TLS validation bypass should NEVER be used in production environments
Security Considerations
Current Implementation (Development)
✅ HTTP-only cookies prevent XSS token theft
✅ SameSite=lax provides CSRF protection
⚠️ Hardcoded credentials (not for production)
⚠️ TLS validation disabled in development
Production Recommendations
Replace Hardcoded Credentials
Implement proper authentication flows: export async function login (
email : string ,
password : string
) : Promise < string | null > {
const response = await fetch ( ` ${ backendUrl } /api/autenticacion/iniciar-sesion` , {
method: 'POST' ,
body: JSON . stringify ({ email , password })
});
// ... handle response
}
Remove or conditionally disable the TLS bypass: // Only for local development with self-signed certs
if ( process . env . NODE_ENV === 'development' &&
process . env . ALLOW_SELF_SIGNED === 'true' ) {
process . env . NODE_TLS_REJECT_UNAUTHORIZED = '0' ;
}
Implement token refresh logic: export async function refreshToken () : Promise < string | null > {
const currentToken = await getAuthToken ();
if ( ! currentToken ) return null ;
const response = await fetch ( ` ${ backendUrl } /api/refresh` , {
headers: { 'Authorization' : `Bearer ${ currentToken } ` }
});
// ... handle refresh
}
export async function logout () : Promise < void > {
const token = await getAuthToken ();
if ( token ) {
await fetch ( ` ${ backendUrl } /api/logout` , {
method: 'POST' ,
headers: { 'Authorization' : `Bearer ${ token } ` }
});
}
// Clear cookie
const cookieStore = await cookies ();
cookieStore . delete ( 'auth_token' );
}
Integration Example
Complete authentication flow:
// app/api/auth/route.ts
import { loginSilent , getAuthToken } from '@/app/actions/auth' ;
export async function GET () {
const existingToken = await getAuthToken ();
if ( existingToken ) {
return Response . json ({ authenticated: true });
}
const token = await loginSilent ();
if ( token ) {
return Response . json ({ authenticated: true , token });
}
return Response . json ({ authenticated: false }, { status: 401 });
}
// app/components/ProtectedComponent.tsx
import { getAuthToken } from '@/app/actions/auth' ;
export default async function ProtectedComponent () {
const token = await getAuthToken ();
if ( ! token ) {
redirect ( '/login' );
}
// Fetch protected data
const data = await fetch ( ` ${ process . env . NEXT_PUBLIC_BACKEND_API_URL } /api/data` , {
headers: { 'Authorization' : `Bearer ${ token } ` }
});
return < div >{ /* Render protected content */ } </ div > ;
}
Error Handling
The loginSilent function handles errors gracefully:
HTTP Errors
if ( ! response . ok ) {
const errorText = await response . text ();
console . error ( `[Auth] Error de login ( ${ response . status } ):` , errorText );
return null ;
}
Network Errors
try {
// ... authentication logic
} catch ( error ) {
console . error ( '[Auth] Excepción en loginSilent:' , error );
return null ;
}
Response Validation
if ( data . estado === 'exito' && data . data ?. token ) {
// Success
} else {
console . error ( '[Auth] Respuesta de login inesperada:' , data );
return null ;
}