Dan Maby
Dan Maby

Reputation: 1

Next.js 14 + tRPC + Appwrite: Session cookie not being set or persisted

I'm building a Next.js 14 application with tRPC and Appwrite for authentication. The T3 Stack was used as a starting point for this app. I'm encountering an issue where the session cookie is not being set or persisted after a successful login.

Environment:

Steps to reproduce:

Expected behaviour: After successful authentication, the session cookie should be set and persisted, allowing the user to access protected routes.

Actual behaviour: The session cookie is not being set or persisted, resulting in the user being unable to access protected routes and getting stuck in a redirect loop

Relevant code:

  1. Auth Router (src/server/api/routers/auth.ts):
import { cookies } from 'next/headers';

// ... other imports

export const authRouter = createTRPCRouter({
  signIn: publicProcedure
    .input(z.object({
      email: z.string().email(),
      password: z.string(),
    }))
    .mutation(async ({ input }) => {
      const { email, password } = input;
      const { account } = await createAdminClient();

      try {
        const session = await account.createEmailPasswordSession(email, password);
        console.log("Session created:", session);

        cookies().set('appwrite_session', session.secret, {
          httpOnly: true,
          secure: process.env.NODE_ENV === 'production',
          sameSite: 'strict',
          path: '/',
          maxAge: 60 * 60 * 24 // 1 day
        });

        console.log("Cookie set:", cookies().get('appwrite_session'));

        return { success: true };
      } catch (error) {
        console.error("Sign in error:", error);
        return { success: false, error: "Authentication failed" };
      }
    }),
});
  1. Middleware (src/middleware.ts):
import { type NextRequest, NextResponse } from "next/server";
import { createSessionClient } from "./lib/server/appwrite";

export async function middleware(request: NextRequest) {
  console.log("Request URL:", request.url);
  console.log("All headers:", Object.fromEntries(request.headers.entries()));
  console.log("All cookies:", request.cookies.getAll());
  
  const sessionCookie = request.cookies.get('appwrite_session');
  console.log("Session cookie:", sessionCookie);

  if (sessionCookie) {
    const { account } = await createSessionClient(sessionCookie.value);
    try {
      const user = await account.get();
      console.log("Authenticated user:", user.$id);
      return NextResponse.next();
    } catch (error) {
      console.error("Error getting user:", error);
    }
  }

  return NextResponse.redirect(new URL("/signin", request.url));
}

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};
  1. Sign-in Page (src/app/(auth)/signin/page.tsx):
// ... imports and component setup

const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault();
  setLoading(true);

  const formData = new FormData(event.currentTarget);
  const email = formData.get("email") as string;
  const password = formData.get("password") as string;

  signInMutation.mutate(
    { email, password },
    {
      onSuccess: (result) => {
        setLoading(false);
        if (result.success) {
          console.log("Sign-in successful:", result);
          console.log("Cookies after sign-in:", document.cookie);
          if (document.cookie.includes('appwrite_session')) {
            console.log("Session cookie found in browser");
          } else {
            console.log("Session cookie not found in browser");
          }
          setSignInSuccess(true);
          router.push("/account");
        } else {
          // ... error handling
        }
      },
      onError: (error) => {
        // ... error handling
      },
    },
  );
};

Server logs:

Session created: {
  // ... session details
}
Cookie set: {
  name: 'appwrite_session',
  value: 'eyJpZCI6IjY2ZTNkZDA-REMOVED-FOR-BREVITY',
  path: '/'
}
POST /api/trpc/auth.signIn?batch=1 200 in 1930ms
Request URL: http://localhost:3000/account
All headers: {
  // ... headers
}
All cookies: []
Session cookie: undefined
Error getting session: [AppwriteException: User (role: guests) missing scope (account)]
Middleware session: undefined

Browser console logs:

Sign-in successful: {success: true}
Cookies after sign-in: 
Session cookie not found in browser

I've tried setting the cookie using both the cookies() API from Next.js and manually setting the Set-Cookie header. Neither approach seems to result in the cookie being set or persisted in the browser.

Any help or insights would be greatly appreciated. Thank you!

Upvotes: 0

Views: 144

Answers (0)

Related Questions