A complete, production-ready fullstack authentication setup using Next.js frontend and ASP.NET Core backend, with secure session cookies, OTP login via SMS, reCAPTCHA validation, and multi-device setup over local or public networks.
Building a Secure Authentication System with ASP.NET Core and Next.js
🚀 Overview
This guide walks through setting up a secure user authentication system in a microservices-like architecture with a React-based frontend (Next.js) and a .NET Core backend (ASP.NET Core). It features:
🚀 Introduction
In modern web development, creating a robust authentication system that works seamlessly across separate frontend and backend services can be challenging. In this article, I’ll walk through how to implement a secure authentication flow using ASP.NET Core for the backend API and Next.js for the frontend, with special attention to cookie-based authentication across different subdomains.
Architecture Overview
- Our system will consist of:
- Backend: ASP.NET Core 9 API running on api.app.local
- Frontend: Next.js 15 application running on app.local
- Authentication: Cookie-based with Identity, supporting:
- Email/password login
- Cross-subdomain cookie sharing
- Secure development setup
🔐 Cookie-based session authentication (HttpOnly, Secure, SameSite=None)
- 📱 OTP login via SMS (phone number-based authentication)
- ✅ Google reCAPTCHA integration
- 🔁 Session sliding expiration
- 🌐 Cross-device and cross-network communication
- 📦 Deployment-ready structure
🧩 Tech Stack
- Frontend: Next.js (Server-Side Rendering, API routes)
- Backend: ASP.NET Core (v7 or later)
- Identity: ASP.NET Core Identity for user management
- SMS Gateway: Custom or Twilio/Any SMS service
- Security: reCAPTCHA v2/v3, Rate Limiting, IP restriction, Anti-spam
- Tunnel: Dev Tunnel (VS) or ngrok for public exposure
🏗 Project Structure
/next-app
/pages
/login
/verify
/dashboard
/middleware.ts
/lib/session.ts
/components
next.config.js
/aspnet-api
/Controllers
/Services
/Models
/Startup.cs
/Program.cs
🔧 Step-by-Step Setup
- 🔐 ASP.NET Core Secure Cookie Setup
services.Configure<CookieAuthenticationOptions>(IdentityConstants.ApplicationScheme, options =>
{
options.Cookie.Name = "RFUM";
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.HttpOnly = true;
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.Domain = ".dev.rfum.local";
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.SlidingExpiration = true;
});
2. 🧠 Identity OTP Token Setup
var token = await _userManager.GenerateChangePhoneNumberTokenAsync(user, user.PhoneNumber);
3. 🌐 Cross-Origin & Cookie Setup
In Startup.cs:
services.AddCors(options =>
{
options.AddPolicy("AllowClient",
builder =>
{
builder.WithOrigins("https://app.dev.rfum.local")
.AllowCredentials()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
4. 🛡 Next.js Session Middleware
export async function middleware(req: NextRequest) {
const cookie = req.cookies.get('RFUM');
if (!cookie) {
return NextResponse.redirect(new URL('/login', req.url));
}
return NextResponse.next();
}
In fetch calls:
await fetch("https://api.dev.rfum.local/api/auth/status", {
credentials: "include"
});
5. 🤖 Google reCAPTCHA v3
In Next.js login form:
const token = await grecaptcha.execute('site_key', { action: 'login' });
Send to backend and verify with Google API.
6. 📱 OTP SMS Flow
- On login with phone, server generates token.
- Sends SMS to phone with 6-digit code.
- User enters code.
- Backend verifies token with Identity.
- Add rate limit per IP, session TTL, and block after X retries.
Development Setup
7. 🌍 Networking Across Devices
Option A: Dev Tunnel (Visual Studio)
Expose ASP.NET Core app via:
https://purple-tiger-12345.devtunnels.ms
Use same domain in Next.js.
Option B: Local DNS + nginx reverse proxy
Add in /etc/hosts:
127.0.0.1 api.dev.rfum.local
127.0.0.1 app.dev.rfum.local
Use nginx to proxy /api/ to ASP.NET Core, and / to Next.js.
-
Local DNS Configuration
Add to your hosts file:
127.0.0.1 app.local
127.0.0.1 api.app.local -
HTTPS Certificates
Create trusted local certificates
mkcert -install
mkcert "app.local" "api.app.local" -
Running the Projects
ASP.NET Core:
dotnet run --urls "https://api.app.local:5001"
Next.js:
NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem" next dev -H app.local -p 3000
✅ Best Practices
- Store refresh timestamps client-side, refetch session every 10 minutes.
- Use HttpOnly cookies with .dev.rfum.local as domain.
- Use separate ports and subdomains for frontend and backend.
- Protect OTP with IP throttling + CAPTCHA.
- Centralize session and token management.
- Add MFA with Google Authenticator for enterprise-ready auth.
🔚 Final Words
This authentication architecture is ideal for scalable, secure fullstack applications. Whether you’re building a dashboard, SaaS platform, or enterprise portal — combining ASP.NET Identity with Next.js’s SSR gives you the best of both worlds.
📦 If you’d like the full zip with source code, ping me and I’ll share it!