Skip to content

Nr 10 Authentication

DodaTech 4 min read

title: "Next.js vs Remix — Authentication Patterns Compared" description: "Compare authentication implementation in Next.js and Remix including session management, protected routes, auth providers, and middleware patterns." weight: 20 date: 2026-06-28 lastmod: 2026-06-28 tags: [frameworks, react]

Authentication in Next.js and Remix follows different patterns due to their middleware and data loading approaches. Both support session-based and token-based auth.

What You'll Learn

You will understand how to implement authentication in both frameworks, manage sessions, protect routes, and integrate with auth providers.

Why It Matters

Authentication is required in most web applications. Choosing the right pattern for your framework prevents security issues and maintenance headaches.

Real-World Use

Durga Antivirus Pro uses Next.js with NextAuth.js for its customer-facing portal. DodaZIP uses Remix with session cookies for its internal admin panel.

flowchart LR
    subgraph Next[Next.js Auth]
        A1[NextAuth.js] --> B1[Middleware protection]
        A2[Server Session] --> B2[Layout-level check]
        A3[Client Session] --> B3[Client Components]
    end
    subgraph Remix[Remix Auth]
        C1[Session Storage] --> D1[Loader protection]
        C2[Cookie Session] --> D2[requireUser utility]
        C3[Form-based login] --> D3[Action handler]
    end
    style Next fill:#121212,color:#fff
    style Remix fill:#1a1a2e,color:#fff

Next.js with NextAuth.js

NextAuth.js is the most common authentication library for Next.js.

// app/api/auth/[...nextauth]/route.js
import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';

const handler = NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
  ],
  callbacks: {
    async session({ session, token }) {
      session.user.id = token.sub;
      return session;
    },
  },
});

export { handler as GET, handler as POST };

Protected pages use middleware or getServerSession.

// middleware.js
export { default } from 'next-auth/middleware';
export const config = { matcher: ['/dashboard/:path*'] };

Expected output: NextAuth.js handles OAuth login. Middleware protects dashboard routes. getServerSession provides session data in Server Components.

Remix Session Authentication

Remix uses session cookies managed through the session storage API.

// app/session.server.js
import { createCookieSessionStorage } from '@remix-run/node';

const storage = createCookieSessionStorage({
  cookie: {
    name: '__session',
    secrets: [process.env.SESSION_SECRET],
    sameSite: 'lax',
    path: '/',
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    maxAge: 60 * 60 * 24 * 7, // 1 week
  },
});

export async function getSession(request) {
  const cookie = request.headers.get('Cookie');
  return storage.getSession(cookie);
}

export async function requireUser(request) {
  const session = await getSession(request);
  const userId = session.get('userId');
  if (!userId) {
    throw redirect('/login');
  }
  return userId;
}
// app/routes/login.jsx — login action
export async function action({ request }) {
  const formData = await request.formData();
  const email = formData.get('email');
  const password = formData.get('password');

  const user = await db.users.verify(email, password);
  if (!user) {
    return { error: 'Invalid credentials' };
  }

  const session = await getSession(request);
  session.set('userId', user.id);
  session.set('role', user.role);

  return redirect('/dashboard', {
    headers: { 'Set-Cookie': await storage.commitSession(session) },
  });
}

Expected output: Users log in via form submission. The session cookie is set on success. Protected routes use requireUser to redirect unauthenticated users.

Protected Route Comparison

Next.js protects routes through middleware or by checking the session in Server Components and redirecting.

Remix protects routes by calling requireUser at the top of each protected loader.

Auth Provider Integration

Next.js integrates with NextAuth.js for OAuth providers, email/password, and credentials.

Remix integrates with any auth provider through custom actions. Use libraries like remix-auth for OAuth.

Common Mistakes

  1. Not using httpOnly cookies for sessions: Client-accessible cookies are vulnerable to XSS. Always set httpOnly: true for session cookies.

  2. Exposing session data to client components in Next.js: Session data from getServerSession should stay in Server Components. Pass only serializable user data to Client Components.

  3. Not checking auth in every Remix loader: Each loader that needs authentication must call requireUser. One unprotected loader can expose data.

  4. Storing user data in the session: Store only the user ID in the session. Fetch current user data from the database on each request.

  5. Not handling token refresh: For JWT-based auth, handle token refresh in middleware or loaders. Expired tokens should redirect to login.

Practice Questions

  1. How does Next.js protect API routes?

Use getServerSession in the API route handler to check authentication. Return 401 if not authenticated.

  1. How does Remix handle session management?

Through the session storage API. Create a cookie session, commit it after login, and read it in loaders.

  1. What is the purpose of httpOnly in session cookies?

It prevents JavaScript from accessing the cookie, protecting against XSS attacks.

  1. How do you log out in Remix?

Call storage.destroySession() and redirect to the login page with the cookie header to clear the session.

  1. Can Next.js middleware check authentication for Server Components?

Yes. Middleware runs before the request. Redirect unauthenticated users before they reach Server Components.

Challenge

Implement a complete authentication flow in both frameworks: login page with email/password, session management, protected dashboard, and logout. Include error handling for invalid credentials.

Frequently Asked Questions

Should I use JWT or session-based auth?

Both work in both frameworks. JWT is stateless and scales better. Session cookies are simpler for server-rendered apps.

Can I use NextAuth.js with the App Router?

Yes. NextAuth.js v5+ supports the App Router natively with route handlers and Server Component integration.

Does Remix have an auth library like NextAuth.js?

Remix does not have a single dominant auth library. Use remix-auth for OAuth or implement custom session-based auth.

How do I handle role-based access control?

Store the user role in the session. In loaders and Server Components, check the role and redirect or return 403 if unauthorized.

Can I use third-party auth providers with Remix?

Yes. Use remix-auth with OAuth strategies for Google, GitHub, and other providers.

Mini Project

Build an authentication system with login, session management, protected routes, role-based access (admin vs user), and logout. Implement in both frameworks.

What's Next

Compare {{< ilink "deployment options" "Deployment" > }} for Next.js and Remix.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro