【问题标题】:Make get request to third party API with api key using express.router();使用 express.router() 使用 api 密钥向第三方 API 发出获取请求;
【发布时间】:2019-12-16 00:27:56
【问题描述】:

我正在构建一个 React 应用程序,并在其中从第三方站点检索数据,这需要我使用“X-Auth-Token”在标头中发送 API 密钥。

目前我正在使用来自客户端 js 文件的 fetch() api 发出此请求。 我知道这是不好的做法,我应该隐藏我的 api 密钥,所以这就是我想要做的,但我发现很难理解所有组件如何在这个难题中组合在一起......

我已经按照教程进行操作,现在有一个 create-react-app 项目在本地侦听端口 3000,还有一个 express 服务器(使用 express.router())在本地侦听端口 9000。

我想从快递服务器向第三方发出api请求,然后发送到前端。

  1. 使用 express.router(),我如何向包含我的 api 密钥的第三方发出请求,然后将其发送到前端?
  2. 当我最终托管这个项目时(我在 heroku 上托管),而不是前端向 port9000 发出 fetch 请求以从 express 服务器请求中检索数据,它应该监听什么 url? - 我想我对这部分缺乏理解。

【问题讨论】:

    标签: javascript reactjs api express express-router


    【解决方案1】:

    您说得对,您应该像中间人一样使用将您的数据检索到您的前端。当然有几个实现。我个人喜欢无服务器方法,为此使用 AWS lambda 函数。但回到你的方法。我可能会使用 axios 模块来检索数据,非常简单明了。您可以将 x-auth-token 标头传递给实例

    
    const express = require('express');
    const axios = require('axios');
    
    const app = express()
    
    const axiosInstance = axios.create({
        baseURL: '<some-domain>',
        headers: { 'X-Auth-Token' : '<some-token>'}
    });
    
    app.get('/data', async(req, res, next) => {
        try {
            const response = await axiosInstance.get('/<path>');
            // process your data and send back to the user
        } catch (error) {
            // handle if you got an error
        }
    })
    
    

    这只是一个展示,我假设你的应用程序看起来不同,但我认为你从这个 sn-p 中得到了一些方向。

    我会将令牌隐藏到环境变量中。

    当您将服务器部署到 heroku 时,您将获得一个 url,在您的前端,您可以轻松替换该 url 并进行部署。

    【讨论】:

    • 感谢您的回答。我不熟悉 Axios,但这个概念似乎很有意义。我可以问一下 - baseURL 大概是第三方 API 的 url。 '/data' - 这到底指的是什么,与 '/' 相同?
    • 是的,basURL 是第三方 API 的 url。 axisosInstace.get(/&lt;path&gt;) 这里的 是第 3 方路径,例如如果您需要在请求中到达其他路径,例如 some-data.com/newdata --> 这里是 /newdata 是路径。如果您没有路径,请保留为“/”。 app.get('/data 是您的服务器的端点,您的反应应用程序在您的本地主机 localhost:9000/data 中调用,但正如我所提到的,我不知道您的代码它可以是其他任何东西。
    • 非常感谢您的帮助。实际上,我使用的是 express-generator,它完全是矫枉过正并且不断抛出错误,我认为我在路由上做错了,但我无法解决。我用单个 app.js 文件替换了它,并包含了这种获取我通过此服务器页面从前端成功检索的数据的方法。现在我只需要重构我的 react 应用程序中的逻辑来处理这些数据。
    【解决方案2】:

    环境变量在这两种情况下都会为您提供帮助。您可以使用dotenv 库。简化了代码示例以专注于您的问题。

    1. 假设您的 React 应用程序向后端端点 (localhost:9000/endpoint) 发出请求,该端点将从第三方服务请求数据(在本例中使用 got 库) ,你会从环境变量中获取授权密钥:
    require('dotenv').config();  // init env vars
    const got = require('got');
    const express = require('express');
    
    const router = express.Router();
    
    // getting API key from env variable
    const apiKey = process.env.AUTH_KEY;
    
    // GET localhost:9000/endpoint
    router.get('/endpoint', async (req, res) => {
      // requesting data from 3rd party service
      const response = await got('https://thirdpartyservice.com/api', {
        headers: {
          'x-auth-token': apiKey, // the auth token header
          json: true, // assuming response will be "application/json"
        },
      });
    
      // passing data to React
      res.json(JSON.parse(response));
    });
    
    1. 您还应该将后端服务 URL 存储在环境变量中。您可能有两个 .env 文件分别用于开发和生产环境:

    发展:

    # .env file on your localhost
    AUTH_KEY = <your_secret_key>
    API_URL=localhost:9000/
    

    生产:

    # env vars on heroku
    AUTH_KEY = <your_secret_key>
    API_URL=<api_server_name>.herokuapp.com/
    

    并将 URL 传递给您的 React 应用程序:

    require('dotenv').config();  // init env vars
    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    
    // your api server URL from env vars
    const apiUrl = process.env.API_URL;
    
    // pass the api URL to your React app
    ReactDOM.render(
      <App apiUrl={ apiUrl } />,
      document.getElementById('root'),
    );
    

    【讨论】:

    • 嗨@Anton,非常感谢您在这里的回答。 Sandor 的回答与我当前的版本更相似,并且已经尝试过并且可以正常工作,所以我会同意,但感谢您抽出宝贵时间回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 2017-09-20
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多