简体   繁体   中英

Make get request to third party API with api key using express.router();

I am building a react app, and in it I am retrieving data from a third party site which requires me to send the API key in the header using 'X-Auth-Token'.

Currently I am making this request using fetch() api from the clientside js files. I understand this is bad practice and I should hide my api key, so this is what I am trying to do but am finding it hard to understand how all the components fit together in this puzzle...

I have followed a tutorial and now have a create-react-app project listening locally on port 3000, and an express server (using express.router()) listening locally on port 9000.

I want to make the api request to the third party from the express server, and then send that to the front end.

  1. using express.router(), how would i make a request to a third party that includes my api key, and then send that on to the front end?
  2. when i eventually host this project (i am hosting on heroku), instead of the front end making a fetch request to port9000 to retrieve the data from the express server request, what url should it be listening to? - I think i lack understanding when it comes to this part.

You are on point, you should use like a middleman to retrive your data to your frontend. There are couple of implementation of course. Personally I like the serverless approach, using AWS lambda functions for it. But back to your approach. I would retrive the data using probably the axios module, very easy and straightforward. You can pass the x-auth-token header to the instance


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
    }
})

It is just a showcase, I assume your application looks different, but I think you got some direction from this snippet.

I would hide the token to an environment variable.

When you deploy your server to heroku you are going to get an url, and in your front-end you can replace the url easily and deploy it.

Environment variables will help you in both cases. You can use dotenv library. The code examples are simplified to focus on your issue.

  1. Assuming your React app makes a request to a back-end endpoint ( localhost:9000/endpoint ) which will be requesting data from the third party service (in this case using got library), you will get the auth key from environment variable:
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. You should store the back-end service URL in an environment variable as well. You might have two .env files for development and production environments respectively:

Development:

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

Production:

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

And passing the URLs to your React app:

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'),
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM