I’ve got NextAuth (mostly) working. The only case where I have issues is when I get redirected to the login page (with a callback in the url parameters) by the middleware. Then, no matter what I do, the app router will not push/replace/refresh the page. I know it’s getting to that block of code, but it just does not do anything.
My login function:
const [serverError, setServerError] = useState<string | null>(null);
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
reset,
setError,
} = useForm<TSignUpSchema>({
resolver: zodResolver(signUpSchema),
});
const onSubmit = async (data: TSignUpSchema) => {
let { id, password } = data;
if(id.toLowerCase().startsWith('u')){
id = id.substring(1);
}
const res = await signIn("credentials", {
id,
password,
redirect: false,
});
if (res?.error) {
reset();
if (res?.status === 401) {
setServerError("Invalid credentials. Please try again");
}
if (res?.status === 418) {
setServerError(
"Something went wrong.nIf this problem continues, contact support."
);
}
}
if (res && res.ok) {
router.replace('/map'); **//THIS DOES NOT WORK AFTER MIDDLEWARE REDIRECT**
}
};
Middleware.ts
import { withAuth } from "next-auth/middleware";
export default withAuth({
pages: {
signIn: '/login', // Redirect to this page if not authenticated
},
});
export const config = {
matcher: ['/map'], // Protect all routes under (protected)
};
app/api/auth/[…nextauth]/route.ts
const authOptions = {
secret: process.env.NEXTAUTH_SECRET,
session: {
strategy: 'jwt', // Use JSON Web Tokens for session handling
maxAge: 24 * 60 * 60 * 30, // Session will last 30 days
updateAge: 24 * 60 * 60 * 10, // Extend session duration by 10 days on each use
},
callbacks: {
async jwt({ token, user }) {
if (user) {
token.id = user.id;
token.email = user.email;
token.name = user.name;
}
return token;
},
async session({ session, token }) {
session.user.id = token.id;
session.user.email = token.email;
session.user.name = token.name;
return session;
}
},
providers: [
CredentialsProvider({
id: 'credentials',
name: "Credentials",
credentials: {
id: { label: "ID", type: "text" },
password: { label: "Password", type: "password" }
},
authorize: async (credentials) => {
const result = signUpSchema.safeParse(credentials);
if (result.error) return null;
try {
//check username/password and return user if valid
} catch (e) {
console.error(e);
return null;
}
}
})
]
};
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
I’m expecting router to replace current page with ‘/map’ after succesfull login…..instead it just sits there.