Catégories
Astuces et Design

Comment détourner du trafic en utilisant IP2Location dans un site Web Next.js – SitePoint

Cet article a été créé en partenariat avec IP2Location. Merci de soutenir les partenaires qui rendent SitePoint possible.

Dans un monde où le commerce en ligne est devenu la norme, nous devons créer des sites Web plus rapides, conviviaux et plus sécurisés que jamais. Dans cet article, vous apprendrez à configurer un site Web propulsé par Node.js capable de diriger le trafic vers les pages de destination pertinentes en fonction du pays du visiteur. Vous apprendrez également à bloquer le trafic anonyme (par exemple Tor) afin d'éliminer les risques provenant de ces réseaux.

Pour mettre en œuvre ces fonctionnalités, nous utiliserons le service Web IP2Proxy fourni par IP2Location, un fournisseur de solutions Geo IP. Le service Web est une API REST qui accepte une adresse IP et répond avec des données de géolocalisation au format JSON.

site web ip2location

Voici certains des champs que nous recevrons:

  • nom du pays
  • Nom de Ville
  • isProxy
  • proxyType
  • etc.

Nous utiliserons Next.js pour créer un site Web contenant les pages de destination suivantes:

  • Page d'accueil: La récupération et la redirection de l'API se déclencheront à partir de cette page
  • Page de destination: les pays pris en charge verront la page du produit dans leur devise locale
  • Page non disponible: d'autres pays verront cette page avec une option pour rejoindre une liste d'attente
  • Page d'abus: les visiteurs utilisant les réseaux Tor seront redirigés vers cette page

Maintenant que vous connaissez le plan du projet, voyons ce dont vous avez besoin pour commencer.

Conditions préalables

Sur votre machine, je recommande fortement ce qui suit:

  • Dernière version LTS de Node.js (v12)
  • Fil

Une version plus ancienne de Node.js suffira, mais la version LTS (prise en charge à long terme) la plus récente contient des améliorations de performances et de débogage dans le domaine du code asynchrone, que nous traiterons. Le fil n'est pas nécessaire, mais vous bénéficierez de ses performances plus rapides si vous l'utilisez.

Je vais également supposer que vous avez une bonne base dans:

Comme mentionné précédemment, nous utiliserons Next.js pour créer notre site Web. Si vous êtes novice, vous pouvez suivre leur didacticiel interactif officiel pour vous mettre rapidement au courant.

Procédure pas à pas du projet IP2Location + Next.js

Configuration du projet

Pour configurer le projet, lancez simplement le terminal et accédez à votre espace de travail. Exécutez la commande suivante:

npx create-next-app

N'hésitez pas à donner un nom à votre application. J'ai appelé le mien next-ip2location-example. Une fois l'installation terminée, accédez à la racine du projet et exécutez yarn dev. Cela lancera le serveur de développement Node.js. Si vous ouvrez votre navigateur et accédez à localhost:3000, vous devriez voir une page avec l'en-tête "Welcome to Next.js". Cela devrait confirmer que nous avons une application qui fonctionne sans erreur. Arrêtez l'application et installez les dépendances suivantes:

yarn add yarn add next-compose-plugins dotenv-load next-env @zeit/next-css bulma isomorphic-unfetch

Nous utiliserons le framework Bulma CSS pour ajouter un style prêt à l'emploi pour notre site. Puisque nous allons nous connecter à un service API, nous allons configurer un .env fichier pour stocker notre clé API. Notez que ce fichier ne doit pas être stocké dans un référentiel. Créez ensuite le fichier next.config.js. à la racine du projet et ajoutez le code suivant:

const withPlugins = require("next-compose-plugins");
const css = require("@zeit/next-css");
const nextEnv = require("next-env");
const dotenvLoad = require("dotenv-load");

dotenvLoad();

module.exports = withPlugins((nextEnv(), 

));

La configuration ci-dessus permet à notre application de lire le .env fichier et charger les valeurs. Notez que les clés devront avoir le préfixe NEXT_SERVER_ afin d'être chargé dans l'environnement du serveur. Visitez la page du package next-env pour plus d'informations. Nous définirons la clé API dans la section suivante. La configuration ci-dessus donne également à notre application Next.js la possibilité de prétraiter le code CSS via le zeit/next-css paquet. Cela nous permettra d'utiliser le framework CSS Bulma dans notre application. Notez que nous aurons besoin d'importer du code CSS Bulma dans notre application Next.js. Je vais bientôt vous montrer où faire cela.

Obtention de la clé API pour le service Web IP2Proxy

Comme mentionné précédemment, nous devons convertir l'adresse IP d'un visiteur en informations que nous pouvons utiliser pour rediriger ou bloquer le trafic. Rendez-vous simplement sur le lien suivant et inscrivez-vous pour une clé d'essai gratuite:

Paquets de clés d'essai ip2proxy

Une fois inscrit, vous recevrez la clé API gratuite par e-mail. Créé un .env fichier et placez-le à la racine de votre dossier de projet. Copiez votre clé API dans le fichier comme suit:

NEXT_SERVER_IP2PROXY_API=

Cette clé gratuite vous donnera 1 000 crédits gratuits. Au minimum, nous aurons besoin des champs suivants pour que notre application fonctionne:

Si vous regardez la section des prix sur la page IP2Proxy, vous remarquerez que le PX2 le paquet nous donnera la réponse requise. Cela signifie que chaque requête nous coûtera deux crédits. Voici un exemple de la façon dont l'URL doit être construite:

  • http://api.ip2proxy.com/?ip=8.8.8.8&key=demo&package=PX2

Vous pouvez également soumettre la requête URL sans l'IP. Le service utilisera l'adresse IP de la machine qui a envoyé la demande. Nous pouvons également utiliser le PX8 package pour obtenir tous les champs disponibles tels que isp et domain dans le package le plus haut du service Web de détection IP2Proxy.

  • http://api.ip2proxy.com/?key=demo&package=PX8

Dans la section suivante, nous allons créer un système de gestion d'état simple pour stocker les données proxy qui seront partagées entre toutes les pages du site.

API de création de contexte dans Next.js

Créer le fichier context/proxy-context et insérez le code suivant:

import React, { useState, useEffect, useRef, createContext } from "react";

export const ProxyContext = createContext();

export const ProxyContextProvider = (props) => {
  const initialState = {
    ipAddress: "0.0.0.0",
    countryName: "Nowhere",
    isProxy: false,
    proxyType: "",
  };

  // Declare shareable proxy state
  const (proxy, setProxy) = useState(initialState);
  const prev = useRef();

  // Read and Write Proxy State to Local Storage
  useEffect(() => {
    if (proxy.countryName == "Nowhere") {
      const localState = JSON.parse(localStorage.getItem("ip2proxy"));
      if (localState) {
        console.info("reading local storage");
        prev.current = localState.ipAddress;
        setProxy(localState);
      }
    } else if (prev.current !== proxy.ipAddress) {
      console.info("writing local storage");
      localStorage.setItem("ip2proxy", JSON.stringify(proxy));
    }
  }, (proxy));

  return (
    
      {props.children}
    
  );
};

Fondamentalement, nous déclarons un état partageable appelé proxy qui stockera les données extraites du service Web IP2Proxy. La requête de récupération d'API sera implémentée dans pages/index.js. Les informations seront utilisées pour rediriger les visiteurs vers les pages pertinentes. Si le visiteur essaie de rafraîchir la page, l'état enregistré sera perdu. Pour éviter que cela ne se produise, nous allons utiliser le useEffect() hook pour conserver l'état dans le stockage local du navigateur. Lorsqu'un utilisateur actualise une page de destination particulière, l'état du proxy est récupéré à partir du stockage local, il n'est donc pas nécessaire d'effectuer à nouveau la requête. Voici un bref aperçu du stockage local de Chrome en action:

stockage local chrome

Conseil: Si vous rencontrez des problèmes plus loin dans ce didacticiel, la suppression du stockage local peut aider à résoudre certains problèmes.

Affichage des informations de proxy

Créer le fichier components/proxy-view.js et ajoutez le code suivant:

import React, { useContext } from "react";
import { ProxyContext } from "../context/proxy-context";

const style = {
  padding: 12,
};

const ProxyView = () => {
  const (proxy) = useContext(ProxyContext);
  const { ipAddress, countryName, isProxy, proxyType } = proxy;

  return (
    
  • IP Address : {ipAddress}
  • Country : {countryName}
  • Proxy : {isProxy}
  • Proxy Type: {proxyType}
); }; export default ProxyView;

Il s'agit simplement d'un composant d'affichage que nous placerons à la fin de chaque page. Nous ne créons cela que pour confirmer que notre logique d'extraction et l'état de l'application fonctionnent comme prévu. Vous devez noter que la ligne const (proxy) = useContext(ProxyContext) ne courra pas tant que nous n’aurons pas déclaré notre Context Provider à l'origine de notre application. Faisons-le maintenant dans la section suivante.

Implémentation du fournisseur d'API contextuelle dans l'application Next.js

Créer le fichier pages/_app.js et ajoutez le code suivant:

import React from "react";
import App from "next/app";
import "bulma/css/bulma.css";
import { ProxyContextProvider } from "../context/proxy-context";

export default class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props;

    return (
      
        
      
    );
  }
}

le _app.js Le fichier est le composant racine de notre application Next.js où nous pouvons partager l'état global avec le reste des pages du site et des composants enfants. Notez que c'est également là que nous importons du CSS pour le framework Bulma que nous avons installé précédemment. Avec cette configuration, créons maintenant une mise en page que nous utiliserons pour toutes les pages de notre site.

Construction d'un modèle de présentation

Créez le dossier layout à la racine de votre projet. Déplaçons le fichier components/nav.js à layout/nav.js. Remplacez le code actuel par ceci:

import React from "react";
import Link from "next/link";

const Nav = () => (
  
);

export default Nav;

Notez qu'il s'agit d'un menu de navigation incomplet, car il est censé être entièrement réactif. Veuillez consulter la documentation de Navbar pour ajouter la prise en charge des écrans de tablette et mobiles.

Je voudrais également souligner que le Home le lien n'utilise pas le Link composant. J'ai fait cela intentionnellement afin que lorsqu'un utilisateur clique dessus, il déclenche une demande GET du serveur. Le reste des liens effectuera uniquement la navigation côté client.

Ensuite, créez le fichier layout/layout.js et ajoutez le code suivant:

import Head from "next/head";
import Nav from "./nav";
import ProxyView from "../components/proxy-view";

const Layout = (props) => (
  
IP2Location Example
); export default Layout;

Maintenant que nous avons le Layout défini, commençons à construire nos pages de site, en commençant par la page d'accueil.

Construire notre page d'accueil

C'est ici que nous effectuerons notre requête de récupération d'API pour le service Web IP2Proxy. Nous enregistrerons la réponse reçue dans notre ProxyContext Etat. Tout d'abord, nous allons rapidement créer uniquement l'interface utilisateur. Ouvrez le dossier pages/index.js et remplacez le code existant par ce qui suit:

import Head from "next/head";
import Layout from "../layout/layout";

const Home = () => {
  return (
    
      
        Home
      

      

Home

Checking availability in your country...

); }; export default Home;

C'est le bon moment pour lancer le serveur de développement Next.js à l'aide de la commande yarn dev ou npm run dev. Vous devriez obtenir la sortie suivante:

mise en page de la page d'accueil

Notez que le ProxyView composant affiche les valeurs initiales que nous avons définies dans le ProxyContextProvider. Dans la section suivante, nous allons effectuer une action d'extraction et mettre à jour ces valeurs.

Exécution d'une requête d'extraction sur le service Web IP2Proxy

Dans cette section, nous allons écrire une fonction asynchrone pour effectuer la requête d'extraction d'API. Nous le ferons dans la fonction getInitialProps. Les résultats seront transmis au Home composant où ils seront enregistrés dans le proxy état mondial via le ProxyContext. De plus, nous utiliserons la page d'erreur intégrée pour rendre les erreurs détectées par notre code. Tout d'abord, définissons le getInitialProps fonction en mettant à jour le code pages/index.js:

import fetch from "isomorphic-unfetch";

//const Home...{}

Home.getInitialProps = async ({ req }) => {
  if (req) {
    // This code'll run in server mode
    const api_key = process.env.NEXT_SERVER_IP2PROXY_API || "demo";
    const ipAddress =
      req.headers("x-forwarded-for") || req.connection.remoteAddress;
    const localAddresses = ("::1", "127.0.0.1", "localhost");
    // Construct IP2Proxy web service URL
    let proxyUrl = `https://api.ip2proxy.com/?key=${api_key}&package=PX2`;
    // If ipAddress is not localhost, add it to the URL as a parameter
    if (!localAddresses.includes(ipAddress))
      proxyUrl = proxyUrl.concat(`&ip=${ipAddress}`);
    try {
      const response = await fetch(proxyUrl);
      const json = await response.json();
      console.log(json);
      if (json.response != "OK")
        return { errorCode: 500, errorMessage: json.response };
      const { isProxy, proxyType, countryName } = json;
      const newProxy = { ipAddress, isProxy, proxyType, countryName };
      return { newProxy };
    } catch (error) {
      return {
        errorCode: error.code,
        errorMessage: error.message.replace(api_key, "demo"),
      };
    }
  }
  return { newProxy: null }; // This line will run in client mode
};

export default Home;

Ensuite, mettons à jour notre composant Accueil:

import React, { useContext, useEffect } from "react";
import Error from "next/error";
import { ProxyContext } from "../context/proxy-context";

const Home = ({ newProxy, errorCode, errorMessage }) => {
  // Display error messages
  if (errorCode) {
    return ;
  }

  // Save new proxy state
  const (proxy, setProxy) = useContext(ProxyContext);
  useEffect(() => {
    let ignore = false;
    if (newProxy && !ignore) {
      setProxy(newProxy);
    }
    return () => {
      ignore = true;
    };
  }, (newProxy));

  // return (...
};

Après avoir enregistré les modifications, actualisez la page. Vous devriez maintenant voir les champs dans ProxyView mise à jour des composants. Prenez note de la sortie affichée dans le terminal:

{
  response: 'OK',
  countryCode: 'KE',
  countryName: 'Kenya',
  proxyType: '-',
  isProxy: 'NO'
}

Les informations ci-dessus doivent refléter le pays dans lequel vous vous trouvez. L'étape suivante consiste à rediriger, mais commençons par créer nos pages de destination manquantes.

Création de pages de destination

Les pages de destination sont assez simples à créer, car elles ont une logique minimale. Utilisez le menu de navigation pour confirmer que chaque page s'affiche correctement une fois que vous avez ajouté le code ci-dessous pour chacun des fichiers:

pages / landing.js:

import React, { useContext } from "react";
import Head from "next/head";
import Layout from "../layout/layout";
import { ProxyContext } from "../context/proxy-context";

const Landing = () => {
  let localPrice = 25000; // Kenyan Shilling
  let exchangeRate = 0;
  let currencySymbol = "";
  const (proxy) = useContext(ProxyContext);
  const { countryName } = proxy;

  switch (countryName) {
    case "Kenya":
      exchangeRate = 1;
      currencySymbol = "KShs.";
      break;
    case "United Kingdom":
      currencySymbol = "£";
      exchangeRate = 0.0076;
      break;
    default:
      break;
  }
  // Format localPrice to currency format
  localPrice = (localPrice * exchangeRate)
    .toFixed(2)
    .replace(/d(?=(d{3})+.)/g, "$&,");

  return (
    
      
        Landing
      

      

Landing Page

Product is available in {countryName}!

); }; export default Landing;

page de destination

pages / indisponible.js:

import React, { useContext } from "react";
import Head from "next/head";
import Layout from "../layout/layout";
import { ProxyContext } from "../context/proxy-context";

const Unavailable = () => {
  const (proxy) = useContext(ProxyContext);
  const { countryName } = proxy;

  return (
    
      
        Unavailable
      

      

Sorry. Product is not available in {countryName}{" "}

Click to join waiting list

); }; export default Unavailable;

page indisponible

pages / abuse.js:

import React from "react";
import Head from "next/head";
import Layout from "../layout/layout";

const Abuse = () => (
  
    
      Abuse
    

    

Sorry! TOR Visitors not allowed

As much as we respect individual privacy, we would rather protect ourselves from users abusing privacy networks{" "}

); export default Abuse;

page d'abus

Maintenant que nous avons implémenté toutes nos pages de destination, nous devons les rediriger automatiquement. Dirigez-vous vers la section suivante.

Détourner le trafic vers les pages de destination pertinentes

Pour effectuer la redirection dans Next.js, nous devons utiliser le useRouter crochet du next/router pour accéder à la router composant. Nous utiliserons la fonction router.replace() pour effectuer la redirection. Il y a deux actions de redirection différentes que nous devons définir:

  1. La première redirection est destinée à bloquer le trafic Tor et à renvoyer vers la page «abus».
  2. La deuxième redirection est destinée à détourner le trafic vers les pages «d'atterrissage» ou «non disponibles».

Ouvert pages/index.js et ajoutez le code suivant:

import { useRouter } from "next/router";

const Home = ({ newProxy, errorCode, errorMessage }) => {
  //...

  // Declare router
  const router = useRouter();

  // Redirect if Proxy Type is TOR
  useEffect(() => {
    if (proxy.proxyType == "TOR") {
      router.replace("/abuse");
    }
  }, (proxy));

  // Redirect based on visitor's country
  const { countryName } = proxy;
  useEffect(() => {
    if (countryName != "Nowhere" && newProxy.proxyType !== "TOR") {
      redirectPage(router, countryName);
    }
  }, (proxy));

  //...
};

const redirectPage = (router, countryName) => {
  let redirectPage;
  switch (countryName) {
    case "Kenya": // Replace with your country's name
      redirectPage = "/landing";
      break;
    case "United Kingdom":
      redirectPage = "/landing";
      break;
    default:
      redirectPage = "/unavailable";
  }
  router.replace(redirectPage);
};

dans le redirectPage , remplacez «Kenya» par le nom de votre pays. Vous pouvez ajouter plus de pays si vous le souhaitez. Cependant, à des fins de test, nous devons restreindre le nombre de pays, car le nombre de pays pris en charge par un service proxy est limité. En parlant de tests, nous devons d'abord déployer notre application.

Conseil: Si vous souhaitez tester manuellement sans déployer, attribuez simplement ipAddress constante avec une adresse IP d'un autre pays. Vous pouvez également tester les adresses IP TOR en en saisissant une dans cette liste d'adresses IP Tor.

Déployer notre application Next.js

La façon la plus simple et la plus rapide de déployer notre application Next.js sur un serveur de production consiste à utiliser la plate-forme de déploiement sans serveur de Vercel. Tout ce que vous avez à faire pour commencer est d'installer leur Now CLI. Vous n'aurez qu'à vérifier votre adresse e-mail pour utiliser le service gratuit.

Si nous devions déployer notre application maintenant, elle fonctionnerait comme prévu. Cependant, il atteindra la limite de 20 crédits gratuits, car nous avons conçu notre application pour utiliser le demo clé si nous n'avons pas spécifié de clé API. Pour télécharger notre clé maintenant, exécutez simplement la commande suivante:

now secrets add NEXT_SERVER_IP2PROXY_API 

Vous pouvez en savoir plus sur la gestion des variables d'environnement et des secrets sur le tableau de bord Vercel ici. Avec cela défini, déployer notre application est aussi simple que d'exécuter la commande suivante:

now --prod

La commande exécutera automatiquement le processus de génération, puis le déploiera sur les serveurs de Vercel. L'ensemble du processus devrait se dérouler en moins d'une minute. L'URL du serveur de production sera automatiquement copiée dans votre presse-papiers. Ouvrez simplement un nouvel onglet sur votre navigateur et collez l'URL. Vous devriez voir quelque chose de similaire à ci-dessous:

déploiement de production

Test du site avec des services de proxy gratuits

Pour confirmer que notre application peut rediriger en fonction du pays d'origine, nous allons utiliser un service proxy gratuit pour émuler différents emplacements. Saisissez simplement l'URL publique de votre application et choisissez un serveur, ou laissez-le au hasard.

formulaire de procuration hma

Dans mon cas, les pays Kenya et Royaume-Uni se dirigeront vers la page de destination.

atterrissage proxy hma

Tout autre pays sera redirigé vers la page «indisponible».

proxy hma non disponible

Test du site avec le navigateur Tor

Voyons maintenant si notre site Web peut bloquer le trafic provenant des réseaux Tor. Visitez simplement le site Web de Tor et installez le navigateur Tor pour votre plate-forme. Voici une capture d'écran de ce à quoi devrait ressembler le site Web:

test du navigateur tor

Conseil: Si vous rencontrez des difficultés pour installer Tor sur votre ordinateur, il peut être plus facile d'installer et d'exécuter le navigateur Tor sur votre appareil Android ou IOS.

Option de base de données locale

Avant de terminer cet article, je voudrais mentionner qu'IP2Location propose des versions de base de données de leurs services Web. Il se présente sous la forme d'un fichier CSV qui peut être importé dans n'importe quel système de base de données que vous préférez. Au lieu d'interroger le service Web distant, vous pouvez créer votre propre service Web local à l'aide de la base de données, ce qui devrait entraîner une réponse plus rapide. Notez que lorsque vous achetez une base de données, elle est mise à jour quotidiennement. Par conséquent, vous devrez automatiser quotidiennement le processus de téléchargement et d'importation de nouvelles données dans votre base de données locale.

Vous vous demandez comment nous allons déployer une base de données dans une architecture sans serveur? C’est assez simple. Déployez votre base de données sur un service cloud tel que MongoDb ou FaunaDb. Cependant, le déploiement de votre base de données sur un autre serveur annule les avantages d'avoir une base de données locale. Ma recommandation est d'utiliser des conteneurs Docker pour empaqueter et déployer votre application et votre base de données au sein du même serveur ou centre de données pour gagner en vitesse.

Sommaire

J'espère que vous avez maintenant la confiance nécessaire pour créer un site qui peut rediriger les utilisateurs vers des pages de destination pertinentes en fonction du pays dans lequel ils naviguent. Grâce aux informations fournies par les services IP2Location, vous pouvez aller plus loin dans votre site Web en:

  • offrant différents coupons ou offres à différents emplacements géographiques
  • mettre en œuvre la détection des fraudes par carte de crédit en comparant la position d'un visiteur à l'adresse géographique réelle du titulaire de la carte.

Si vous regardez le service Web IP2Location, vous remarquerez qu'il offre un ensemble différent de champs de géolocalisation que vous pouvez utiliser dans votre application. Si vous souhaitez combiner les services Web IP2Location et IP2Proxy dans une seule application, vous pouvez consulter ce projet que j'ai construit plus tôt qui vous montrera comment cela se fait.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *