1

Hi I have tried all things possible to find out what could be causing above error on my live website built using NEXTJS.

I have noticed that this error happens whenever I reload the website.

I also notice that whenever I try to login using userName and password, I am able to do that without any errors in local host and also using https://codesandbox.io. But on the live site I get a server error "problem with the server configuration.".

when I scroll further on my developer tools I find the following additional information.

Unexpected token < in JSON at position 0 {error: {…}, path: "session", message: "Unexpected token < in JSON at position 0"

I have added the following environment variables in vercel

NEXTAUTH_URL = https://****.vercel.app/
MONGODB_URI = mongodb+srv://****@cluster0.9kc5p.mongodb.net/*****?retryWrites=true&w=majority

my [...nextauth].js file is as below

import NextAuth from "next-auth";
import CredentialsProviders from "next-auth/providers/credentials";
import { verifyPassword } from "../../../lib/hashedPassword";

import clientPromise from "../../../lib/mongodb";

export default NextAuth({
  session: {
    strategy: "jwt"
  } /* check other providers you may add database etc */,
  providers: [
    CredentialsProviders({
      /* authorize will be called when it receives incoming login req */
      async authorize(credentials) {
        const client = await clientPromise;
        const db = client.db();
        /* check if we have user or email */
        const usersCollection = await db.collection("users");

        const user = await usersCollection.findOne({
          $or: [
            { email: credentials.email },
            { userName: credentials.userName }
          ]
        });

        if (!user) {
          throw new Error("No user found");
        }
        const isvalid = await verifyPassword(
          credentials.password,
          user.password
        );

        if (!isvalid) {
          throw new Error("password is invalid");
        }

        return {
          email: user.email
        }; 
      }
    })
  ]
});

my login page is as below

import Button from "../../UI/Button/Button";
import Input from "../../UI/Input/Input";
import Card from "../../UI/card/Card";
import classes from "./Login.module.css";
import Link from "next/link";
import { useForm } from "react-hook-form";
import { signIn, getSession } from "next-auth/react";
import { useRouter } from "next/router";

const Login = () => {
  const route = useRouter();
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm();

  const submittedFormHandler = async (userInputs) => {
    const result = await signIn("credentials", {
      redirect: false,
      email: userInputs.userNameEmail,
      userName: userInputs.userNameEmail,
      password: userInputs.password
    }); /* result will always resolve */
    if (!result.error) {
      route.replace("/");
    }
  };

  return (
    <>          

      <Card className={classes.login}>
        <form onSubmit={handleSubmit(submittedFormHandler)}>
          
          <Input
            htmlFor="userNameEmail"
            id="userNameEmail"
            label="UserName or Email"
            input={{
              type: "text",
              ...register("userNameEmail", { required: true})
            }}
          ></Input>
          <span className={classes.spanning}>
            {errors.userName &&
              "Enter userName or Email at least four characters"}
          </span>

          <Input
            htmlFor="password"
            id="password"
            label="Enter Password"
            input={{
              type: "password",
              ...register("password", { required: true, minLength: 8 })
            }} 
          ></Input>
          <span className={classes.spanning}>
            {errors.password && "password should be at least 8 characters"}
          </span>
          <div className={classes.password}>
            <Button type="submit">Submit</Button>
            <Link href="/ForgotPassword">Forgot Password ?</Link>
          </div>
          <Link href="/NewUser" className={classes.link}>
            Create Account New User
          </Link>
        </form>
      </Card>
    </>
  );
};


export async function getServerSideProps(context) {
  const session = await getSession({
    req: context.req
  }); //returns session obj or null
  if (session) {
    return {
      redirect: {
        destination: "/",
        permanent: false
      }
    };
  }
  return {
    props: { session }
  };
}

export default Login;

what could be the problem? please assist

17
  • server configuration is a server-side problem. Why are you looking at the client for clues? Commented Jan 19, 2022 at 10:32
  • I am checking on both sides, the biggest challenge is why the code works on local host but it cant login me in online Commented Jan 19, 2022 at 12:03
  • what is the status code of the response ?? Commented Jan 19, 2022 at 12:10
  • 1
    Is it possible for you to visualize the Serverless Function logs on vercel.app ? Commented Jan 19, 2022 at 14:07
  • 1
    I am suspecting something is going bust on that server with respect to mongodb(either connectivity or schema, or data), etc... Commented Jan 19, 2022 at 14:08

2 Answers 2

1

I faced the same problem, but i was using mysql as database and i didn't use the auth file middleware that suggest next-auth to handle the providers, instead i created a separated file to handle sequelize (in your case will be the orm with the database you're using).

I fixed it adding dialectModule to the propertys of the class Sequelize

const db = new Sequelize(`${process.env.DB_URI}`, {
  database: process.env.DB_NAME,
  logging: false,
  dialect: "mssql",
  dialectModule: require("mysql2"),
});
Sign up to request clarification or add additional context in comments.

Comments

0

I also have this problem. They said on the doc that make sure you define NEXTAUTH_URL variable correctly. If you use Vercel to host, then the content of the variable should be only the url without quote. For example, https:project.vercel.app.

If not solved, try changing the [...nextauth].ts file to a more simple version. I got this error when I tried doing things with database in the callback (mongodb in my case) like this

 async jwt({ token }) {
    let role:Role = 'user'
    if (!token.email) throw Error('no email provided with token')
    let user = await getUser(token.email)
    if (user?.isAdmin) role = 'admin'
    return {...token, role}
 }

After removing this, my problem is solved. In your case, you could try removing anything that deals with the database.

After I got that working, I added this callback function instead

 async jwt({ token }) {
    let role:Role = 'user'
    if (!token.email) throw Error('no email provided with token')
    const client = await clientPromise
    const collection = client.db().collection('users')
    const user = await collection.findOne({email:token.email})
    if (user?.isAdmin) role = 'admin'
    return {...token, role}
}

The only difference is that the first one use mongoose, and the second one doesn't. The approach of the second one is taken from https://github.com/vercel/next.js/tree/canary/examples/with-mongodb

Disclaimer: I don't know why it worked.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.