下一个身份验证凭据

Tra*_*gar 6 next.js next-auth

我正在尝试使用 进行凭据身份验证next-auth。我必须使用自定义登录页面,但我绝对无法让它工作大约一整周。

\n

我有 :

\n

\r\n
\r\n
// [...nextauth.js]\n\nimport NextAuth from \'next-auth\';\nimport Providers from \'next-auth/providers\';\n\nimport axios from \'@api/axios\';\n\nconst options = {\n  providers: [\n    Providers.Credentials({\n      async authorize(credentials) {\n        const { data: user, status } = await axios.post(\'/users/authentication\', credentials);\n\n        if (user && status === 200) {\n          return user;\n        } else {\n          throw new Error(\'error message\');\n        }\n      }\n    })\n  ],\n  pages: {\n    signIn: \'/profil/authentication/login\',\n    error: \'/profil/authentication/login\'\n  },\n  session: {\n    jwt: true,\n    maxAge: 30 * 24 * 60 * 60 // 30 days\n  },\n  debug: true\n};\n\nexport default (req, res) => NextAuth(req, res, options);
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

和 :

\n

\r\n
\r\n
// profil/authentication/login\n\nimport { signOut, useSession } from \'next-auth/client\';\n\nimport AuthenticationForm from \'@components/auth/authenticationForm\';\nimport Layout from \'@components/layout\';\n\nconst Login = () => {\n  const [session] = useSession();\n  const intl = useIntl();\n\n  return (\n    <Layout>\n      {!session && <AuthenticationForm />}\n      {session && (\n        <>\n          Signed in as {session.user.email}\n          <br />\n          <button onClick={signOut}>Sign out</button>\n        </>\n      )}\n    </Layout>\n  );\n};\n\nexport default Login;
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

\r\n
\r\n
// authenticationForm.js\n\nimport { signIn, csrfToken } from \'next-auth/client\';\nimport { useRouter } from \'next/router\';\nimport { useEffect, useState } from \'react\';\n\nimport PasswordInput from \'@components/auth/passwordInput\';\nimport Button from \'@components/form/button\';\nimport TextInput from \'@components/form/textInput\';\n\nconst AuthenticationForm = ({ csrf }) => {\n  const [username, setUsername] = useState(\'\');\n  const [password, setPassword] = useState(\'\');\n  const [error, setError] = useState(\'\');\n  const router = useRouter();\n\n  const handleChangeUsername = ({ target: { value } }) => setUsername(value);\n\n  const handleChangePassword = ({ target: { value } }) => setPassword(value);\n\n  const handleLogin = () => {\n    signIn(\'credentials\', {\n      username,\n      password,\n      callbackUrl: `${window.location.origin}/profil`\n    })\n      .then((res) => {\n        console.log(\'form::res -> \', res);\n        router.back();\n      })\n      .catch((e) => {\n        console.log(\'form::e -> \', e);\n        setError(\'login error\');\n      });\n  };\n\n  useEffect(() => {\n    if (router.query.error) {\n      setError(router.query.error);\n      setUsername(router.query.username);\n    }\n  }, [router]);\n\n  return (\n    <form onSubmit={handleLogin}>\n      <TextInput\n        name="username"\n        value={username}\n        onChange={handleChangeUsername}\n      />\n      <PasswordInput handleChange={handleChangePassword} />\n      {error && <div>{error}</div>}\n      <Button type="submit">\n      connexion\n      </Button>\n      <input name="csrfToken" type="hidden" defaultValue={csrf} />\n    </form>\n  );\n};\n\nAuthenticationForm.getInitialProps = async (context) => {\n  return {\n    csrf: await csrfToken(context)\n  };\n};\n\nexport default AuthenticationForm;
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

肯定是NEXTAUTH_URL=http://localhost:3000.env.local.

\n

如果我继续/profil/authentication/login,我会看到我的表单,当我单击“连接”时,我总是出现一些错误,例如:"Failed to fetch",仅此而已,或者:

\n
\n

[next-auth][错误][client_fetch_error] (2)\xc2\xa0["/api/auth/csrf", TypeError: 无法获取]\nhttps://next-auth.js.org/errors#client_fetch_error

\n
\n

即使我尝试删除表单中的所有 csrf 处理并让登录“单独执行是的”。

\n

我真的被这个库困住了,我很可能会换成另一个库,但我想知道我做错了什么?是否有一个完整的示例,其中包含自定义登录页面和在同一登录页面上处理的错误。这是非常基本的,我不明白为什么我不能轻易找到它。

\n

小智 1

@特拉尔加

我认为这个问题与后端的 CSRF 策略有关,如果您在 localhost 上,那么 localhost:3000 和 localhost:2000 就像两个不同的域。只需确保您的后端 cors 策略中是否有前端域(如果在本地主机上,则必须带有端口)