首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当NEXTAUTH_URL不能工作时,如何定义自定义基路径?

当NEXTAUTH_URL不能工作时,如何定义自定义基路径?
EN

Stack Overflow用户
提问于 2022-01-14 22:31:05
回答 2查看 5.6K关注 0票数 4

上下文

我用的是NextJS v12.0.7React v17.0.2NextAuth v4.1.0Typescript v4.3.5

我想要创建一个简单的auth系统,它基于NextAuth文档,登录后被重定向到主页,所以我在名为[...nextauth].tspages/api/auth文件夹中创建了一个文件,其中包含以下代码:

代码语言:javascript
运行
复制
export default NextAuth({
  providers: [
    CredentialsProvider({
      id: "credentials",
      name: "Login",
      credentials: {
        username: { type: "email" },
        password: { type: "password" },
      },
      async authorize(credentials) {
          // [...]
      },
    }),
  ],

  // [...]

  callbacks: {
    // [...]
    redirect({ url, baseUrl }) {
      console.log("redirect - url ", url, "baseUrl ", baseUrl); // This is what I was checking
      if(url.startsWith(baseUrl)) {
        return url
      } else if(url.startsWith("/")) {
        return new URL(url, baseUrl).toString();
      }
      return baseUrl;
    }
  },
})

对于我的NextJS项目,我使用在next.config.js文件中定义的basepath /espace-personnel,所以我在.env.local文件中按照官方的NextAuth文档定义了NEXTAUTH_URL

代码语言:javascript
运行
复制
NEXTAUTH_URL=http://localhost/espace-personnel/api/auth

我的问题

当我在重定向回调中检查urlbaseUrl变量时,我可以看到,我的NEXTAUTH_URL变量没有很好地定义,或者我遇到了一些问题。

以下是console.log("redirect - url ", url, "baseUrl ", baseUrl);的结果:

代码语言:javascript
运行
复制
redirect - url  http://localhost:3000 baseUrl  http://localhost

我做过研究,在谷歌或Stackoverflow上找不到任何像我这样的案例,我是NextAuth的新手,所以我可能误解了什么。有人知道我做错了什么吗?

编辑(15/01/2022)

经过反复考虑,我决定直接使用process.env.NEXTAUTH_URL检查env变量,因此我在前面的console.log()之后添加了这一行:

代码语言:javascript
运行
复制
  console.log("NEXTAUTH_URL", process.env.NEXTAUTH_URL)

其结果是:

代码语言:javascript
运行
复制
NEXTAUTH_URL http://localhost/espace-personnel/api/auth

所以,事实上,这不是定义NEXTAUTH_URL的问题,我想我误解了NextAuth的工作方式,我将继续尝试找到解决我的问题的方法,如果我发现了什么,就在那里分享。

编辑(16/01/2022)

经过一些研究,我发现我们可以使用callbackUrl方法传递signIn,所以我在[...nextauth].ts中定义了这样的页面:

代码语言:javascript
运行
复制
  pages: {
    signIn: process.env.NEXT_PUBLIC_BASE_URL + '/connexion',
    signOut:  process.env.NEXT_PUBLIC_BASE_URL + '/deconnexion',
    error:  process.env.NEXT_PUBLIC_BASE_URL + '/connexion/erreur', // Error code passed in query string as ?error=
  },

这是我的登录表格的代码:

代码语言:javascript
运行
复制
import React, { useState } from "react";
import Alert from "../../ui/Alert/Alert";
import Button from "../../ui/Button/Button";
import Card from "../../ui/Card/Card";
import Divider from "../../ui/Divider/Divider";
import { getCsrfToken, signIn } from "next-auth/react";
import Input from "../../ui/Input/Input";
import styles from "./LoginForm.module.scss";
import Router from 'next/router';

type TAlertTitle = string;
type TAlertMessage = string;
type TAlertType = "info" | "warning" | "success" | "error";

export default function LoginForm({ csrfToken }: { csrfToken: string }) {
  const [alertTitle, setAlertTitle] = useState<TAlertTitle>("Information");
  const [alertMessage, setAlertMessage] = useState<TAlertMessage>("Juste un exemple");
  const [alertType, setAlertType] = useState<TAlertType>("info");

  async function onSubmit(event: React.SyntheticEvent<HTMLFormElement>) {
    const target = event.target as typeof event.target & {
      username: { value: string },
      password: { value: string },
    };

    // Login attempt
    const result = signIn('credentials', {
      callbackUrl: process.env.NEXT_PUBLIC_BASE_URL,
      username: target.username.value,
      password: target.password.value
    });

    console.log(result);

    event.preventDefault();
  }

  return (
    <Card className={styles.card}>
      <p className={'textSize40 fontWeightExtraBold textAlignCenter'}>
        Connexion à votre espace personnel
      </p>
      <Divider className={styles.divider} />
      <form onSubmit={onSubmit}>
        <Alert title={alertTitle} message={alertMessage} type={alertType}></Alert>
        <input name="csrfToken" type="hidden" defaultValue={csrfToken} />
        <Input id="username" name="username" className="width100" type="email" autoComplete="email" placeholder="Adresse mail" leftIconLib="line-awesome" leftIcon="envelope" required />
        <Input id="password" name="password" className="width100" type="password" autoComplete="current-password" placeholder="Mot de passe" leftIconLib="line-awesome" leftIcon="key" required />
        <Button className="width100" theme="accent" type="submit">Se connecter</Button>
        <Button className="width100" type="submit">Identifiants oubliés</Button>
      </form>
    </Card>
  );

}

新的问题是,当我尝试登录时,我被重定向到http://localhost/api/auth/error,并获得了这个错误:

代码语言:javascript
运行
复制
404 | This page could not be found.

我是不是做错什么了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-16 20:22:05

经过几个小时的研究,我终于遇到了一个最近关于同一问题的讨论

在NextAuth v4中使用自定义基路径的解决方案

这是简短的版本,更长的是在底部。

  1. NEXTAUTH_URL文件中定义.env,用自己的basePath替换/espace-personnel
代码语言:javascript
运行
复制
NEXTAUTH_URL=http://localhost/espace-personnel/api/auth
  1. basePath中定义<SessionProvider>_app.tsx道具,用自己的basePath替换/espace-personnel
代码语言:javascript
运行
复制
function App({ Component, pageProps: { session, ...pageProps } }: AppProps) {
  return (
    <SessionProvider session={session} basePath='/espace-personnel/api/auth'>
      <Component {...pageProps} />
    </SessionProvider>
  );
}
export default App

与NextAuth v4一起使用自定义基路径的解决方案(以前的解决方案)

在本例中,使用的basePath/espace-personnel,域是localhost

您需要在您的NEXTAUTH_URL文件中设置.env环境变量,包括您的basePath和后面的/api/auth,如下所示:

代码语言:javascript
运行
复制
NEXTAUTH_URL=http://localhost/espace-personnel/api/auth

然后编辑_app.tsx并使用<SessionProvider>上的支持basePath定义基本路径,下面是使用自定义路径/espace-personnel的最后代码:

代码语言:javascript
运行
复制
function App({ Component, pageProps: { session, ...pageProps} }: AppProps) {
  return (
    <SessionProvider session={session} basePath="/espace-personnel/api/auth">
      <Component {...pageProps} />
    </SessionProvider>
  )
}
export default App
票数 9
EN

Stack Overflow用户

发布于 2022-03-19 12:10:48

如果您使用带有多个区域或自定义基路径的next.js auth,则需要进行一些更改以使NextAuth.js知道这一点。

更新rest路径库,.env文件

代码语言:javascript
运行
复制
NEXTAUTH_URL=https://example.com

成为

代码语言:javascript
运行
复制
NEXTAUTH_URL=https://example.com/{zone name or basePath}/api/auth

更新客户端api路径库,_app.tsx

代码语言:javascript
运行
复制
<SessionProvider session={pageProps.session}>

成为

代码语言:javascript
运行
复制
<SessionProvider session={pageProps.session} basePath="/{zone name or basePath}/api/auth">
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70717224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档