Does Laravel Work With Auth.js?
Auth.js is primarily designed for Next.js and JavaScript frameworks, so using it with Laravel requires treating them as separate systems communicating via APIs.
Quick Facts
How Laravel Works With Auth.js
Laravel and Auth.js don't integrate directly since Auth.js is built for Next.js and JavaScript-based frameworks, while Laravel is a PHP backend. However, they can work together in a decoupled architecture where Auth.js handles authentication in a separate Next.js frontend, and Laravel serves as your API backend. Auth.js manages user sessions and JWT tokens on the frontend, which are then sent to Laravel APIs via the Authorization header. Laravel validates these tokens using middleware and serves protected resources accordingly.
This architecture works well for modern full-stack applications but requires careful token management and CORS configuration. You'll need to ensure token expiration policies align between Auth.js and Laravel, handle refresh token logic consistently, and manage user data synchronization if needed. Auth.js can be configured to use custom credentials provider to authenticate against Laravel's login endpoint, returning a JWT that's stored in session.
The developer experience involves maintaining two separate authentication contexts—one in Auth.js for frontend state management and one in Laravel for API authorization. This separation actually provides benefits like independent scaling and flexibility, but adds complexity around keeping auth state synchronized and handling token lifecycle events.
Best Use Cases
Auth.js with Laravel JWT Backend
npm install next-auth axios// pages/api/auth/[...nextauth].ts
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import axios from 'axios';
const LARAVEL_API = process.env.NEXT_PUBLIC_API_URL;
export const authOptions = {
providers: [
CredentialsProvider({
async authorize(credentials) {
try {
const res = await axios.post(`${LARAVEL_API}/api/login`, {
email: credentials?.email,
password: credentials?.password,
});
if (res.status === 200 && res.data.token) {
return {
id: res.data.user.id,
email: res.data.user.email,
name: res.data.user.name,
token: res.data.token,
};
}
return null;
} catch (error) {
throw new Error('Invalid credentials');
}
},
}),
],
callbacks: {
async jwt({ token, user }) {
if (user) token.token = user.token;
return token;
},
async session({ session, token }) {
session.token = token.token;
return session;
},
},
};
export default NextAuth(authOptions);Known Issues & Gotchas
Token expiration mismatch between Auth.js session timeout and Laravel JWT expiry
Fix: Synchronize token lifetimes and implement refresh token rotation in both systems. Configure Auth.js callbacks to handle 401 responses and trigger token refresh via Laravel endpoint.
CORS issues when Auth.js frontend calls Laravel API endpoints
Fix: Configure Laravel's CORS middleware properly with correct origins, credentials: true in fetch requests, and handle preflight requests.
User data duplication and sync issues between Auth.js session and Laravel database
Fix: Use Auth.js callbacks to fetch user data from Laravel API and keep session updated. Implement webhook or polling for data consistency.
Auth.js doesn't natively support Laravel's session-based authentication
Fix: Configure Auth.js with custom credentials provider that authenticates against Laravel login endpoint and exchanges for JWT tokens.
Alternatives
- •Laravel Sanctum + Next.js (native Laravel authentication with SPA support and cookie-based sessions)
- •Keycloak + Laravel (dedicated OAuth2/OIDC server with Laravel as resource server)
- •Firebase Authentication + Laravel (managed authentication service with custom Laravel API validation)
Resources
Related Compatibility Guides
Explore more compatibility guides