Hello, I’m looking for best practices to make Next.js 14 (with App Router) work with Parse. I want to implement a middleware to check if the user is logged in and protect certain routes.
The issue I’m facing is that when I call the getCurrentUser function, it always returns null in the middleware.
I also tried an approach by storing the sessionToken in cookies, but this time when I call the become function in the middleware, I get the following error:
The edge runtime does not support Node.js ‘https’ module. Learn More: Using Node.js Modules in Edge Runtime | Next.js".
I need help, thank you.
// middleware.ts
"use server";
import { NextRequest, NextResponse } from "next/server";
const { getCurrentUser, become } = require("@/lib/api");
import { cookies } from 'next/headers';
const authRoutes = ["/user/*"];
function matchesWildcard(path: string, pattern: string): boolean {
if (pattern.endsWith("/*")) {
const basePattern = pattern.slice(0, -2);
return path.startsWith(basePattern);
}
return path === pattern;
}
export async function middleware(request: NextRequest) {
const LOGIN = `${request.nextUrl.origin}/auth/login`;
if (
authRoutes.some((pattern) =>
matchesWildcard(request.nextUrl.pathname, pattern)
)
) {
const currentUser = await getCurrentUser();
// always null
if (!currentUser) {
return NextResponse.redirect(LOGIN);
}
}
let redirectToApp = false;
if (request.nextUrl.pathname === "/auth/login") {
const token = request.cookies.get('session');
if (token) {
try {
const payload = await become(token.value);
if (payload) {
redirectToApp = true;
} else {
request.cookies.delete('session');
}
} catch (error) {
request.cookies.delete('session');
}
}
}
if (redirectToApp) {
return NextResponse.redirect(`${request.nextUrl.origin}/`);
} else {
return NextResponse.next();
}
}
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};
"use server";
import { cookies } from "next/headers";
import Parse from "../services/parseService";
export const getCurrentUser = async () => {
try {
const user = await Parse.User.current();
return user;
} catch (error) {
console.log("Error: " + error.code + " " + error.message);
}
};
export const become = async (sessionToken) => {
try {
const user = await Parse.User.become(sessionToken);
return true;
} catch (error) {
return false;
}
};
export const signUp = async (data) => {
const user = new Parse.User();
user.set("password", data.password);
user.set("username", data.email);
user
.signUp()
.then(function (user) {
console.log(
"User created successful with name: " +
user.get("username") +
" and email: " +
user.get("email")
);
})
.catch(function (error) {
console.log("Error: " + error.code + " " + error.message);
});
};
export async function logIn(data) {
try {
const user = await Parse.User.logIn(data.email, data.password);
cookies().set("session", user.getSessionToken(), {
httpOnly: true,
});
} catch (error) {
console.log(error);
}
}