[英]client fetch error on live website built using next.js
Hi I have tried all things possible to find out what could be causing above error on my live website built using NEXTJS.嗨,我已经尝试了所有可能的方法来找出在使用 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 .我还注意到,每当我尝试使用用户名和密码登录时,我都可以在本地主机中没有任何错误,并且还可以使用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"
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我在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我的 [...nextauth].js 文件如下
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
请协助
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).我遇到了同样的问题,但是我使用
mysql
作为数据库,并且我没有使用建议 next- auth
的身份验证文件中间件来处理提供程序,而是创建了一个单独的文件来处理续集(在您的情况下将是 orm与您正在使用的数据库)。
I fixed it adding dialectModule
to the propertys of the class Sequelize
我修复了它,将
dialectModule
添加到 class Sequelize
的属性中
const db = new Sequelize(`${process.env.DB_URI}`, {
database: process.env.DB_NAME,
logging: false,
dialect: "mssql",
dialectModule: require("mysql2"),
});
I also have this problem.我也有这个问题。 They said on the doc that make sure you define
NEXTAUTH_URL
variable correctly.他们在文档上说确保您正确定义
NEXTAUTH_URL
变量。 If you use Vercel to host, then the content of the variable should be only the url without quote.如果使用 Vercel 托管,那么变量的内容应该只有 url 没有引号。 For example,
https:project.vercel.app
.例如,
https:project.vercel.app
。
If not solved, try changing the [...nextauth].ts
file to a more simple version.如果没有解决,请尝试将
[...nextauth].ts
文件更改为更简单的版本。 I got this error when I tried doing things with database in the callback (mongodb in my case) like this当我尝试在回调中使用数据库(在我的情况下为 mongodb)时,我得到了这个错误
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在我开始工作后,我添加了这个回调 function
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.唯一的区别是第一个使用 mongoose,第二个没有。 The approach of the second one is taken from https://github.com/vercel/next.js/tree/canary/examples/with-mongodb
第二种方法取自https://github.com/vercel/next.js/tree/canary/examples/with-mongodb
Disclaimer: I don't know why it worked.免责声明:我不知道它为什么起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.