为什么我的 Next.js 项目无法按时正确加载登录页面?

问题描述 投票:0回答:0

我不太确定我在 next.js 电子商务项目的 signin.js route API 中编写的算法有什么问题,但按时正确加载页面非常好,无需等待很长时间(大约1s),但是我一部署到 netlify 中,事情就发生了变化,netlify 的错误页面弹出说

"2023-04-09T13:26:17.617Z 4cba366e-5bdf-4bcc-b6f0-9d6975604105 Task timed out after 10.02 seconds"

我用尽了我所有的选择,花了几天时间试图修复它,并尝试了网络上的许多建议解决方案,但到目前为止没有一个有效,现在感觉真的很绝望。当我在 AWS Amplify 中部署时也会发生同样的事情,而且我的图像甚至没有显示在那里,看到有人在 github 上建议要求 netlify 增加超时限制,但我认为这不会解决问题,因为访问者不会等待页面加载超过 4 秒,我什至不能说我现在有多绝望,花了这么多时间开发这个项目,需要尽快在我的 github 上为我的客户展示,我们将不胜感激任何帮助。

P.S:类似的事情也发生在forgot.js页面,当我输入电子邮件时总是返回 500 或 502,尽管它存在于我的 ddatabase 中! 到目前为止我尝试了什么:

-切换到不同的云平台,如 Amplify、Vercel...

-检查了很多次 .env 文件是否有问题,我很确定它一切正常,并且仔细检查了那里的每个变量。

-更新了项目中的所有包,还重新安装了 node_modules

制作链接: https://musical-lokum-78f90a.netlify.app/

页面 >signin.js

import React from "react";

import styles from "../styles/signin.module.scss";
import { BiLeftArrowAlt } from "react-icons/bi";
import Link from "next/link";

import LoginInput from "../components/custom/loginIput";
import Image from "next/image";
import { signIn } from "next-auth/react";
import { useState } from "react";

import { getProviders } from "next-auth/react";

import { useRouter } from "next/router";
import { getSession } from "next-auth/react";
import BarLoader from "react-spinners/BarLoader";
import {getCsrfToken} from 'next-auth/react'


function Signin({ providers, csrfToken, callbackUrl }) {
  const [user, setUser] = useState({
    email: "",
    password: "",
  });

  const router = useRouter();

  const [message, setMessage] = useState({
    error: "",
    successMessage: "",
  });

  const [loading, setLoading] = useState(false);
  
 

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    const result = await signIn("credentials", {
      redirect: false,
      email: user.email,
      password: user.password,
    });

    if (result?.error) {
      setLoading(false);
      setMessage({ ...message, error: result.error });
    }

    if (result?.ok) {
      const session = await getSession();
      console.log(session);
      const successMessage = "You have successfully logged in !";
      const waitTime = 3000;
      setLoading(false);

      setMessage({ ...message, successMessage });

      let timer = setTimeout(() => {
        router.push(callbackUrl || "/");
      }, waitTime);

      return () => {
        clearTimeout(timer);
      };
    }
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setUser({ ...user, [name]: value });
   
  };

  return (
    <>
     

      <div className={styles.login}>
        <div className={styles.login__container}>
          <div className={styles.login__header}>
            <div className={styles.goback__svg}>
              <BiLeftArrowAlt />
            </div>

            <span>Shop over +1 million products !</span>
          </div>

          <div className={styles.login__form}>
            <Image src="/profilelogo.svg" width={100} height={100} alt="not" />
            <h3>Sign in</h3>
            <p> Sign in and start shopping immediately !</p>

            <form onSubmit={handleSubmit}>
              <LoginInput
                icon="user"
                placeholder="Username"
                onChange={handleChange}
                type="text"
                name="email"
                value={user.email}
                required={true}
              />
              <LoginInput
                icon="password"
                placeholder="Password"
                onChange={handleChange}
                type="password"
                name="password"
                value={user.password}
                required={true}
              />
              {message.error && (
                <div
                  className={styles.login__error}
                  onAnimationEnd={() => setMessage({ ...message, error: "" })}
                  key={message.error}
                >
                  <p>{message.error}</p>
                </div>
              )}

              {message.successMessage && (
                <div
                  className={styles.login__success}
                  onAnimationEnd={() =>
                    setMessage({ ...message, successMessage: "" })
                  }
                  key={message.successMessage}
                >
                  <p>{message.successMessage}</p>
                </div>
              )}

              <div className={styles.links}>
                <span>
                  <Link className={styles.links__span__a} href="/signup">
                    Create an account
                  </Link>
                </span>
                <span>
                  <Link
                    className={styles.links__span__a}
                    href="auth/forgot"
                  >
                    Forgot password
                  </Link>
                </span>
              </div>

              <button className={styles.loginButton} type="submit">
                {
                  loading ? <BarLoader
                  color="#fff"
                  height={5}
                  loading = {loading}
                  speedMultiplier={2}
                  width={100}
                />
                : "Sign in"
                }

              </button>

              <div className={styles.divider}>
                <span>or</span>
              </div>
              { providers &&
                Object.values(providers).map((item, index) =>
                item.id === "credentials" ? null : (
                  <div className={styles.login__social} key={index}>
                    <a onClick={() => signIn(item.id)}>
                      <Image
                        src={`/${item.id}.svg`}
                        width={20}
                        height={20}
                        alt={`${item.name}`}
                      />
                      <span>Continue with {`${item.name}`}</span>
                    </a>
                  </div>
                )
              )}
            </form>
          </div>
        </div>
      </div>

    </>
  );
}

export default Signin;

export async function getServerSideProps(context) {
  const { req, query } = context;
  const providers = await getProviders();

  const session = await getSession({ req });

  const csrfToken = await getCsrfToken(context);
  const { callbackUrl } = query;

  let defaultCallbackUrl = "/";

  if (callbackUrl) {
    defaultCallbackUrl = callbackUrl;
  }

  if (session) {
    return {
      redirect: {
        destination: defaultCallbackUrl,
      },
    };
  }

  return {
    props: { providers, session, csrfToken, callbackUrl: defaultCallbackUrl },
  };
}


pages/api/auth> [...nextauth].js


import NextAuth from 'next-auth'
import GoogleProvider from 'next-auth/providers/google'
import GithubProvider from 'next-auth/providers/github'
import CredentialsProvider from "next-auth/providers/credentials";
import dotenv from 'dotenv'
import User from '../../../models/User'
import bcrypt from 'bcrypt'
import joi from 'joi'
import {connectDB, disconnect} from '../../../utils/db'
import {MongoDBAdapter} from '@next-auth/mongodb-adapter'
import clientPromise from './lib/mongodb'

import { getToken } from 'next-auth/jwt'


dotenv.config()


 const loginSchema = joi.object({
  email: joi.string().email().required(),
  password: joi.string().min(6).required(),

});



export default NextAuth({
     adapter : MongoDBAdapter(clientPromise),
  providers: [
    CredentialsProvider({
      id: 'credentials',
     name : 'Sign in',
      credentials : {
        email: { label: "Username", type: "text", placeholder: "jsmith" },
        password: { label: "Password", type: "password", placeholder: "********" }
      },

      async authorize(credentials,req) {

        try {

         await connectDB()

        const email = credentials.email
        const password = credentials.password
        console.log(email,password)

        if (!email || !password) {
          throw new Error('Please provide an email and password.');
        }

        const {error} = loginSchema.validate({email,password})
        if (error) {
          throw new Error(error.details[0].message);
        }

        const user = await User.findOne({email})

        if (!user) {
          throw new Error('Invalid email or password.');
        }

        const checkMatch = await bcrypt.compare(password, user.password)

        if (!checkMatch) {
          throw new Error('Invalid email or password.');
        }




        return user
      } catch (error) {
        throw new Error(error.message);

      }

      finally
      {
        await disconnect()
        
        
      }
    
      }
      
      }),
 
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret:process.env.GOOGLE_CLIENT_SECRET,

    }),
    GithubProvider({
      clientId: "Iv1.2a94b24ea5010c98",
      clientSecret: "71ff167e340484f06b9e03ff73bb64e4e667f8cb",
    }),
    
  
  ],

  pages: {
    signIn: '/signin',
  },

  callbacks: {
    async session({session, token}) {
    
      
      let user = await User.findById(token.sub);
     
      session.user.id = token.sub || user?._id?.toString();
      session.user.role = user?.role || 'user';      
      return session;
    }
  },

 

    session: {
     
    strategy: 'jwt',


    },
    jwt: {
      secret: process.env.JWT_SECRET,

    },
    secret: process.env.NEXTAUTH_SECRET,




})


错误信息:

.env文件:

reactjs authentication next.js netlify next-auth
© www.soinside.com 2019 - 2024. All rights reserved.