Problema

Tot ce vrei să faci este să aduci niște JSON dintr-un punct final API pentru vreme, câteva recenzii de cărți sau ceva similar.

Interogarea de preluare din front-end este suficient de ușoară, dar trebuie să lipiți cheia secretă API chiar acolo în codul front-end pentru ca oricine să o găsească cu o cantitate banală de săpare!

De asemenea, împingerea cheilor API către depozitul GitHub este o problemă majoră: Dev a pus cheile AWS pe Github. Apoi s-au întâmplat lucruri rele.

“De ce este atât de greu ?!” – Tu, probabil acum 15 minute

Soluția

Ar trebui să utilizați un server back-end ca releu pentru a prelua rezultatele API pentru dvs. și apoi să le transmiteți front-end-ului dvs.

Noua problemă

Încercați doar să faceți o demonstrație front-end pentru portofoliul dvs.! Nu ați aflat încă nimic despre tehnologiile back-end! De ce este atât de greu ?!

Demo

Am întâmpinat această problemă destul de des încât am decis să nu mai vin cu hack-uri stupide și să pun în aplicare o soluție care funcționează cu un cod back-end minim.

În această demonstrație am configurat un back-end care ascultă cererile POST și le trimite către API GoodReads. Pentru a utiliza acest lucru, trebuie să implementați al tau front-end care poate trimite cererea POST corespunzătoare către acest back-end. Front-end-ul dvs. nu va comunica direct cu GoodReads, deci nu este expusă nicio cheie API.

Vei avea nevoie

  • Nodul (acest lucru a fost testat cu v10.16.0, versiunile ulterioare vor fi bune, cele mai vechi pot întâmpina probleme)
  • git
  • Această repo: https://github.com/JacksonBates/example-goodreads-api-relay

Incepe

git clone https://github.com/JacksonBates/example-goodreads-api-relay.git

README.md conține tot ce trebuie să știți, inclusiv instalarea și configurarea.

Am inclus aici punctele cheie pentru comoditate:

README.md

Instalați dependențe:

npm i

Trebuie să-ți creezi propriul .env fișier pentru cheia dvs.:

cp .env.example .env

Apoi deschide noul .env înregistrați și lipiți cheile în locul corect.

Exemplu:

GOODREADS_API_KEY=AABBCCDDEEFF00112233445566778899

Acum rulați serverul:

node app.js

În browser, navigați la localhost: 3000 pentru a confirma că serverul rulează. Ar trebui să vedeți un simplu Hello World!

Ce urmează?

Acum citiți app.js înregistrați temeinic.

Am comentat foarte mult codul pentru a vă ajuta să înțelegeți ce se întâmplă dacă nu ați văzut nodul / exprimarea mult înainte.

// app.js

// These import necessary modules and set some initial variables
require("dotenv").config();
const express = require("express");
const fetch = require("node-fetch");
const convert = require("xml-js");
const rateLimit = require("express-rate-limit");
const app = express();
const port = 3000;

// Rate limiting - Goodreads limits to 1/sec, so we should too

// Enable if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
// see https://expressjs.com/en/guide/behind-proxies.html
// app.set('trust proxy', 1);

const limiter = rateLimit({
	windowMs: 1000, // 1 second
	max: 1, // limit each IP to 1 requests per windowMs
})

//  apply to all requests
app.use(limiter)

// Routes

// Test route, visit localhost:3000 to confirm it's working
// should show 'Hello World!' in the browser
app.get("/", (req, res) => res.send("Hello World!"));

// Our Goodreads relay route!
app.get("/api/search", async (req, res) => {
	try {
		// This uses string interpolation to make our search query string
		// it pulls the posted query param and reformats it for goodreads
		const searchString = `q=${req.query.q}`;

		// It uses node-fetch to call the goodreads api, and reads the key from .env
		const response = await fetch(`https://www.goodreads.com/search/index.xml?key=${process.env.GOODREADS_API_KEY}&${searchString}`);
		//more info here https://www.goodreads.com/api/index#search.books
		const xml = await response.text();

		// Goodreads API returns XML, so to use it easily on the front end, we can
		// convert that to JSON:
		const json = convert.xml2json(xml, { compact: true, spaces: 2 });

		// The API returns stuff we don't care about, so we may as well strip out
		// everything except the results:
		const results = JSON.parse(json).GoodreadsResponse.search.results;

		return res.json({
            success: true,
            results
        })
	} catch (err) {
		return res.status(500).json({
			success: false,
			message: err.message,
		})
	}
})

// This spins up our sever and generates logs for us to use.
// Any console.log statements you use in node for debugging will show up in your
// terminal, not in the browser console!
app.listen(port, () => console.log(`Example app listening on port ${port}!`));

Actualizați: Mulțumiri imense lui Gouri Shankar Kumawat pentru contribuția unui PR care a îmbunătățit acest cod! Îl poți urmări pe Twitter la @dev_gskumawatsau pe GitHub: gskumawat0

Testați releul API

Utilizare Poştaş pentru a testa API-ul.

Setați Postman la GET și lipiți acest lucru în adresa URL: localhost:3000/api/search?q=hobbit

Postman vă va arăta răspunsul JSON de mai jos.

Cum sa evitati expunerea cheii API in aplicatiile publice front end
Captură de ecran a Postman care arată JSON returnat din noul nostru back-end

Cum îl folosiți în front-end?

Această aplicație simplă ascultă cererile de postare la /api/search, deci interacționați cu acesta în aplicația dvs. front-end așa cum ați fost anterior cu API-ul original.

Aceasta este configurată doar pentru a gestiona interogările de căutare – dacă doriți să utilizați alte puncte finale / metode API Goodreads, va trebui să vă gândiți la modul în care le implementați singur!

Gazduire

Nu vă puteți implementa front-end-ul și îl aveți în continuare pe localhost – evident, trebuie să îl implementați și pe acesta.

Vă recomand Heroku.

Credit suplimentar

Dacă doriți să extindeți acest lucru, ați putea lua în considerare modul în care ați putea face acest lucru accesibil doar dintr-o gamă restrânsă de adrese IP pentru a spori securitatea – ceea ce a fost în afara sferei acestui tutorial / demonstrație.


Acest lucru a fost pus în grabă împreună ca răspuns la o discuție pe forum. Dacă observați probleme în această postare sau în exemplul de cod, vă rugăm să nu ezitați să răspundeți la firul de forum care a început totul. Voi menține articolul și repo actualizat cu îmbunătățiri.

Simțiți-vă liber să trimiteți PR dacă aveți contribuții valoroase de făcut 🙂

De asemenea, puteți să mă contactați prin Twitter: @JacksonBates.