【问题标题】:Environment variables not working (Next.JS 9.4.4)环境变量不起作用(Next.JS 9.4.4)
【发布时间】:2020-10-04 18:26:16
【问题描述】:

所以我使用 Contentful API 从我的帐户中获取一些内容并将其显示在我的 Next.Js 应用程序中(我使用的是 next 9.4.4)。这里非常基本。现在为了保护我的凭据,我想使用环境变量(我以前从未使用过它,而且我对这一切都很陌生,所以我有点迷失了)。

我正在使用以下内容在我的 index.js 文件中创建 Contentful Client:

const client = require('contentful').createClient({
    space: 'MYSPACEID',
    accessToken: 'MYACCESSTOKEN',
});

MYSPACEIDMYACCESSTOKEN 是硬编码的,所以我想将它们放在一个 .env 文件中以保护它,并且在 Vercel 上部署时不要将其公开。

我创建了一个.env 文件并像这样填充它:

CONTENTFUL_SPACE_ID=MYSPACEID
CONTENTFUL_ACCESS_TOKEN=MYACCESSTOKEN

当然,MYACCESSTOKENMYSPACEID 包含正确的键。

然后在我的 index.js 文件中,我执行以下操作:

const client = require('contentful').createClient({
  space: `${process.env.CONTENTFUL_SPACE_ID}`,
  accessToken: `${process.env.CONTENTFUL_ACCESS_TOKEN}`,
});

但是当我使用yarn dev 时它不起作用,我收到以下控制台错误:

{
  sys: { type: 'Error', id: 'NotFound' },
  message: 'The resource could not be found.',
  requestId: 'c7340a45-a1ef-4171-93de-c606672b65c3'
}

这是我的主页以及我如何从 Contentful 检索内容并将它们作为道具传递给我的组件:

const client = require('contentful').createClient({
    space: 'MYSPACEID',
    accessToken: 'MYACCESSTOKEN',
});

function Home(props) {
  return (
    <div>
      <Head>
        <title>My Page</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main id="page-home">
        <Modal />
        <NavTwo />
        <Hero item={props.myEntries[0]} />
        <Footer />
      </main>
    </div>
  );
}

Home.getInitialProps = async () => {
  const myEntries = await client.getEntries({
    content_type: 'mycontenttype',
  });

  return {
    myEntries: myEntries.items
  };
};

export default Home;

你认为我的错误来自哪里?

在研究我的问题时,我还尝试了解 api 在 next.js 中的工作原理,因为我已经阅读过在 pages/api/ 中创建 api 请求可能会更好,但我不明白如何获取内容,然后像我在这里所做的那样将响应传递到我的页面组件中..

任何帮助将不胜感激!

编辑:

所以我通过将我的环境变量添加到我的next.config.js 来解决这个问题:

const withSass = require('@zeit/next-sass');

module.exports = withSass({
  webpack(config, options) {
    const rules = [
      {
        test: /\.scss$/,
        use: [{ loader: 'sass-loader' }],
      },
    ];

    return {
      ...config,
      module: { ...config.module, rules: [...config.module.rules, ...rules] },
    };
  },
  env: {
    CONTENTFUL_SPACE_ID: process.env.CONTENTFUL_SPACE_ID,
    CONTENTFUL_ACCESS_TOKEN: process.env.CONTENTFUL_ACCESS_TOKEN,
  },
});

【问题讨论】:

  • 我可以使用 process.env.VARIABLE_NAME 在 getServerSideProps() 中获取 .env.local 变量,但在客户端提交表单时无法获取它们

标签: javascript reactjs environment-variables next.js contentful


【解决方案1】:

参考docs

您需要在项目中添加一个 next.config.js 文件。在该文件中定义环境变量,这些变量将在您的应用程序中可用。

【讨论】:

  • 好的,我知道我的错误是什么。我已将其添加到我的next.config.js,但我做错了。现在它可以工作了,我会编辑我的帖子。谢谢!
  • 可以在node和浏览器环境中直接读取.env文件。我没有机会尝试。早期版本不支持它。
  • @Perdixo,这是不正确的答案,因为建议的方式 公开 凭据。它只能用于可以公开发布的变量。
  • 我和@Perdixo有同样的问题,我的问题仍然是一样的,如果我将环境添加到 next.config.js 我解决了问题,因为我真的不知道为什么如果我创建任何类型的 .env,结果始终未定义,我正在使用下一个 v10,并且我想确保我的凭据没有暴露
  • 此解决方案适用于旧版本。问题的作者应该接受@NikolaiKiselev 的回答。
【解决方案2】:

您不能在不暴露您的 API 凭据的情况下从客户端发出此类请求。你必须有一个后端。

您可以使用 Next.js /pages/api 向 Contentful 发出请求,然后将其传递给您的前端。

只需创建一个.env 文件,添加变量并在您的 API 路由中引用它,如下所示:

process.env.CONTENTFUL_SPACE_ID

从 Next.js 9.4 开始,您不需要 next.config.js。


通过将变量添加到next.config.js 您已经向客户端公开了秘密。任何人都可以看到这些秘密。

New Environment Variables Support

Create a Next.js App with Contentful and Deploy It with Vercel

Blog example using Next.js and Contentful

【讨论】:

    【解决方案3】:
      npm i --save dotenv-webpack@2.0.0 // version 3.0.0 has a bug
    

    在根目录下创建.env.development.local 文件。并在此处添加您的环境变量:

     AUTH0_COOKIE_SECRET=eirhg32urrroeroro9344u9832789327432894@@@
     NODE_ENV=development
     AUTH0_NAMESPACE=https:ilmrerino.auth0.com 
    

    在应用的根目录中创建next.config.js

    const Dotenv = require("dotenv-webpack");
    module.exports = {
      webpack: (config) => {
        config.resolve.alias["@"] = path.resolve(__dirname);
        config.plugins.push(new Dotenv({ silent: true }));
        return config;
      },
    };
    

    但是,这些环境变量将被服务器访问。如果你想使用任何环境变量,你必须再添加一个配置。

     module.exports = {
      webpack: (config) => {
        config.resolve.alias["@"] = path.resolve(__dirname);
        config.plugins.push(new Dotenv({ silent: true }));
        return config;
      },
     env: {
       AUTH0_NAMESPACE: process.env.AUTH0_NAMESPACE,
      },
    };
    

    【讨论】:

      【解决方案4】:

      不要将敏感的东西放在next.config.js 然而在我的情况下,我有一些根本不敏感的环境变量,我需要它们作为服务器端以及客户端,然后你可以这样做:

      // .env file:
      VARIABLE_X=XYZ
      
      // next.config.js
      module.exports = {
        env: {
          VARIABLE_X: process.env.VARIABLE_X,
        },
      }
      

      【讨论】:

        【解决方案5】:

        我建议在 nextjs 9.4 及更高版本更新,使用此示例:

        .env.local
        NEXT_PUBLIC_SECRET_KEY=i7z7GeS38r10orTRr1i
        

        您可以在代码的任何部分使用:

        .js
        const SECRET_KEY = process.env.NEXT_PUBLIC_SECRET_KEY
        

        请注意,它必须与密钥“NEXT_PUBLIC_ SECRET_KEY”的名称相同,而不仅仅是“SECRET_KEY”

        当你运行它时,请确保在日志中说

        $ next dev
        Loaded env from E:\awesome-project\client\.env.local
        ready - started server on http://localhost:3000
        ...
        

        要了解有关环境变量的更多信息,请参阅this link

        【讨论】:

        • 这是使用 NEXT_PUBLIC 所必需的
        • 请注意,这种方法不保护您的秘密 - 前端包中的任何人都可以看到它们。为了保护您的秘密,您必须创建一个后端函数,正如 Nikolai Kiselev 在他的回复中所建议的那样。 .env 文件可用于存储机密,但从不为它们添加前缀“NEXT_PUBLIC_”,因为这使它们也对前端可见。如果没有“NEXT_PUBLIC_”前缀,该变量将仅在您想要的 next.js 后端中可用。
        【解决方案6】:

        如果您使用的是最新版本的 nextJs(9 以上)

        然后按照以下步骤操作:

        1. 在项目的根目录中创建一个 .env.local 文件。
        1. 为所有环境变量添加前缀 NEXT_PUBLIC_
        eg: NEXT_PUBLIC_SOMETHING=12345
        
        1. 在任何带有前缀 process.env 的 JS 文件中使用它们
        eg: process.env.NEXT_PUBLIC_SOMETHING
        

        【讨论】:

        • 这是我需要做的 - NEXT_PUBLIC_ 是我将变量公开给浏览器所缺少的。
        【解决方案7】:

        你必须在 next.config.js 中做一个简单的改变

        const nextConfig = {
          reactStrictMode: true,
          env:{
            MYACCESSTOKEN : process.env.MYACCESSTOKEN,
            MYSPACEID: process.env.MYSPACEID,
          }
        }
        
        module.exports = nextConfig
        

        改成这样

        【讨论】:

          猜你喜欢
          • 2021-03-30
          • 2021-11-13
          • 2020-11-25
          • 1970-01-01
          • 1970-01-01
          • 2022-01-21
          • 2015-09-27
          相关资源
          最近更新 更多