Fermer

décembre 4, 2019

Comment détourner du trafic à l'aide de IP2Location sur un site Web Next.js –


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, plus conviviaux et plus sécurisés que jamais. Dans cet article, vous apprendrez à configurer un site Web optimisé par Node.js, capable de diriger le trafic vers des 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 liés à de tels réseaux.

Pour implémenter ces fonctionnalités, nous allons utiliser 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 aux données de géolocalisation au format JSON.

 Site Web ip2location

Voici quelques-uns des champs que nous allons recevoir:

  • countryName
  • . 19659007] isProxy
  • proxyType
  • etc.

Nous allons utiliser la page Next.js pour créer un site Web contenant les pages de destination suivantes:

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

Maintenant que vous êtes au courant du plan de projet, voyons ce que vous devez faire. pour commencer.

Conditions préalables

Sur votre machine, je vous recommande fortement de suivre ng:

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

Une ancienne version de Node.js fera l'affaire, mais la version la plus récente de LTS (prise en charge à long terme) contient des améliorations en termes de performances et de débogage. la zone de code asynchrone, que nous allons traiter. Le fil n'est pas nécessaire, mais vous l'utiliserez plus rapidement.

Je suppose également que vous avez de bonnes bases en:

Comme mentionné précédemment, nous utiliserons Next .js pour construire notre site web. Si vous débutez, vous pouvez suivre leur didacticiel interactif officiel pour atteindre rapidement votre vitesse de croisière.

Présentation du projet IP2Location + Next.js

Configuration du projet

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 erreurs. Arrêtez l'application et installez les dépendances suivantes:

 fil ajouter un fil ajouter next-composer-plugins dotenv-load suivant-env @ zeit / next-css bulma isomorphic-unfetch

Nous utiliserons le framework CSS Bulma pour ajouter un style original à notre site. Comme nous allons nous connecter à un service d’API, nous allons configurer un fichier .env pour stocker notre clé d’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(),
    [css]
])

La configuration ci-dessus permet à notre application de lire le fichier .env et de charger les valeurs. Notez que les clés doivent avoir le préfixe NEXT_SERVER_ pour pouvoir être chargées dans l'environnement du serveur. Visitez la page du package next-env pour plus d'informations. Nous allons définir 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 package zeit / next-css . Cela nous permettra d'utiliser le framework Bulma CSS dans notre application. Notez que nous aurons besoin d’importer le code CSS Bulma dans notre application Next.js.

Obtention de la clé d’API pour le service Web I2Proxy

Comme indiqué précédemment, nous devons convertir l’adresse IP du visiteur en informations pouvant être utilisées pour rediriger ou bloquer le trafic. Cliquez simplement sur le lien suivant et inscrivez-vous pour obtenir une clé d’essai gratuite:

 Paquets de clé d’essai ip2proxy

Une fois inscrit, vous recevrez la clé API gratuite par courrier électronique. Créez un fichier .env et placez-le à la racine du dossier de votre 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 le bon fonctionnement de notre application:

Si vous consultez la section relative aux prix de la page IP2Proxy, vous remarquerez que le package PX2 nous donnera les informations suivantes: réponse requise. Cela signifie que chaque requête nous coûtera deux crédits. Voici un exemple de la manière dont l’URL doit être construite:

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

Vous pouvez également envoyer le Requête d'URL sans l'adresse IP. Le service utilisera l'adresse IP de la machine qui a envoyé la demande. Nous pouvons également utiliser le package PX8 pour obtenir tous les champs disponibles, tels que les domaines isp et dans le package le plus haut du service Web de détection IP2Proxy. [19659006] http://api.ip2proxy.com/?key=demo&package=PX8

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

API de création de contexte dans Next.js

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

 import React, {
    useState,
    useEffect,
    useRef,
    createContext
} de 'réagir'

export const ProxyContext = createContext ()

export const ProxyContextProvider = (props) => {
    const initialState = {
        ipAddress: '0.0.0.0',
        countryName: 'Nulle part',
        isProxy: faux,
        proxyType: ''
    }

    // Déclarer l'état du proxy partageable
    const [proxy, setProxy] = useState (initialState)
    const prev = useRef ()

    // Lecture et écriture de l'état du proxy sur le stockage local
    useEffect (() => {
        if (proxy.countryName == 'Nowhere') {
            const localState = JSON.parse (localStorage.getItem ('ip2proxy'))
            si (état local) {
                console.info ('lecture du stockage local')
                prev.current = localState.ipAddress
                setProxy (localState)
            }
        } else if (prev.current! == proxy.ipAddress) {
            console.info ('écriture de stockage local')
            localStorage.setItem ('ip2proxy', JSON.stringify (proxy))
        }
    }, [proxy])

    revenir(
        
            {props.children}
        
    )
}

Fondamentalement, nous déclarons un état partageable appelé proxy qui stockera les données extraites du service Web IP2Proxy. La requête d'extraction de l'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 tente d'actualiser la page, l'état enregistré sera perdu. Pour éviter cela, nous allons utiliser le hook useEffect () pour conserver l’état persistant dans la mémoire de stockage locale du navigateur. Lorsqu'un utilisateur actualise une page de destination particulière, l'état du proxy est extrait de la mémoire de stockage locale. Il n'est donc pas nécessaire de réexécuter la requête. Voici un aperçu du stockage local de Chrome en action:

 stockage local chromé

Conseil: Si vous rencontrez des problèmes plus loin dans ce didacticiel, effacer le stockage local peut vous aider à résoudre certains problèmes. 19659050] Affichage des informations sur le proxy

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

 import React, {useContext} à partir de 'react'
importer {ProxyContext} de '../context/proxy-context'

style const = {
    rembourrage: 12
}

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

    revenir (
        
  • Adresse IP: {ipAddress}
  • Pays: {countryName}
  • Proxy: {isProxy}
  • Type de proxy: {proxyType}
) } exporter par défaut ProxyView

Il s’agit simplement d’un composant d’affichage que nous placerons à la fin de chaque page. Nous créons cela uniquement pour confirmer que la logique d'extraction et l'état de l'application fonctionnent comme prévu. Notez que la ligne const [proxy] = useContext (ProxyContext) ne sera exécutée que lorsque nous aurons déclaré notre fournisseur de contexte à la racine de notre application. Faisons-le maintenant dans la section suivante.

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

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

 import Réagissez depuis 'réagir'
importer l'application de 'next / app'
importer 'bulma / css / bulma.css'
importer {ProxyContextProvider} de '../context/proxy-context'

classe par défaut d'exportation MyApp étend App {
  render () {
    const {Composant, pageProps} = this.props

    revenir (
      
        
      
    )
  }
}

Le fichier _app.js est le composant racine de notre application Next.js, dans lequel 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 CSS pour le framework Bulma que nous avons déjà installé. Avec cette configuration, construisons maintenant une mise en page que nous utiliserons pour toutes les pages de notre site.

Construction d’un modèle de mise en page

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

 import Réagissez à partir de 'réagir'
importer un lien de 'next / link'

const Nav = () => (
  
)

exportation par défaut

Notez qu’il s’agit d’un menu de navigation incomplet, car il se veut totalement réactif. Veuillez examiner la documentation de Navbar pour ajouter le support pour les écrans de tablette et mobile.

J'aimerais également souligner que le lien Home n'utilise pas le . Composant Link . Je l'ai fait intentionnellement pour que lorsqu'un utilisateur clique dessus, une requête GET du serveur sera déclenchée. Le reste des liens ne fera que la navigation côté client.

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

 import Head de 'next / head'.
importer Nav de './nav'
importer ProxyView de '../components/proxy-view'

const Layout = (props) => (
  
Exemple d'emplacement IP2
exportation par défaut

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

Construire notre page d'accueil

C'est à cet endroit que nous allons effectuer notre API. chercher la requête pour le service Web IP2Proxy. Nous enregistrerons la réponse reçue dans notre état ProxyContext . Premièrement, nous allons rapidement construire uniquement l’interface utilisateur. Ouvrez le fichier pages / index.js et remplacez le code existant par ce qui suit:

 import Head de 'next / head'
importer une mise en page à partir de '../layout/layout'

const Accueil = () => {
  revenir (
    
      
         Accueil 
      

      

Accueil

Vérification de la disponibilité dans votre pays ...

) } défaut d'exportation

Il est maintenant temps de lancer le serveur de développement Next.js à l'aide de la commande yarn dev ou npm run dev . Vous devriez obtenir le résultat suivant:

 mise en page d'accueil

Notez que le composant ProxyView affiche les valeurs initiales définies dans ProxyContextProvider . Dans la section suivante, nous allons effectuer une opération 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 exécuter la requête d'extraction d'API. Nous le ferons dans la fonction getInitialProps . Les résultats seront transmis au composant Home où ils seront sauvegardés dans l’état global via le ProxyContext . De plus, nous utiliserons la page d’erreur intégrée pour afficher les erreurs interceptées par notre code. Premièrement, définissons la fonction getInitialProps en mettant à jour le code dans pages / index.js :

 importation extraite de 'isomorphic-unfetch'

// const Accueil ... {}

Home.getInitialProps = async ({req}) => {
  if (req) {// Ce code sera exécuté en mode serveur
    const api_key = process.env.NEXT_SERVER_IP2PROXY_API || 'démo'
    const ipAddress = req.headers ['x-forwarded-for'] || req.connection.remoteAddress
    const localAddresses = ['::1', '127.0.0.1', 'localhost']
    // Construire l'URL du service Web IP2Proxy
    let proxyUrl = `https://api.ip2proxy.com/?key=$ {api_key} & package = PX2`
     // Si ipAddress n'est pas localhost, ajoutez-le à l'URL en tant que paramètre
    if (! localAddresses.includes (ipAddress))
      proxyUrl = proxyUrl.concat (`& ip = $ {ipAddress}`)
    essayer {
      réponse const = wait fetch (proxyUrl)
      const json = wait 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}
      retourne {newProxy}
    } catch (error) {
      return {errorCode: error.code, errorMessage: error.message.replace (clé_api, 'demo')}
    }
  }
  return {newProxy: null} // Cette ligne sera exécutée en mode client
}

défaut d'exportation

Maintenant, mettons à jour notre composant Home:

 import React, {
  useContext,
  useEffect,
} de 'réagir'
importer une erreur de 'next / error'
importer {ProxyContext} de '../context/proxy-context'

const Accueil = ({newProxy, errorCode, errorMessage}) => {

  // Afficher les messages d'erreur
  if (code d'erreur) {
    retour 
  }

  // Enregistrer le nouvel état du proxy
  const [proxy, setProxy] = useContext (ProxyContext)
  useEffect (() => {
    laissez ignorer = faux
    if (newProxy &&! ignore) {
      setProxy (newProxy)
    }
     return () => {ignore = true; }
  }, [newProxy])

  // revenir (...
}

Une fois les modifications enregistrées, actualisez la page. Vous devriez maintenant voir les champs dans la mise à jour du composant ProxyView . Prenez note du résultat affiché dans le terminal:

 {
  réponse: 'OK',
  countryCode: 'KE',
  countryName: 'Kenya',
  proxyType: '-',
  isProxy: 'NON'
}

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

Construire des pages de destination

ils ont une logique minimale. Utilisez le menu de navigation pour vérifier que chaque page s'affiche correctement après avoir ajouté le code ci-dessous pour chacun des fichiers:

pages / landing.js :

 import React, {useContext} de 'réagir'
importer Head de 'next / head'
importer une mise en page à partir de '../layout/layout'
importer {ProxyContext} de '../context/proxy-context'

Const Landing = () => {
    let localPrice = 25000 // shilling kenyan
    let exchangeRate = 0;
    let currencySymbol = ''
    const [proxy] = useContext (ProxyContext)
    const {countryName} = proxy

    commutateur (nom de pays) {
        cas 'Kenya':
            exchangeRate = 1;
            currencySymbol = 'KShs.'
            Pause;
        cas 'Royaume-Uni':
            currencySymbol = '£'
            exchangeRate = 0,0076;
            Pause;
        défaut:
            Pause;
    }
    // Format localPrice au format monétaire
    localPrice = (localPrice * exchangeRate) .toFixed (2) .replace (/  d (? = ( d {3}) + .) / g, '$ &,')

    revenir (
        
            
                 Atterrissage 
            

            

Page d'atterrissage

Le produit est disponible à {countryName}!

) } défaut d'exportation

 landing page

pages / indisponible.js :

 import Réagissez, {useContext} à partir de 'réagissez'
importer Head de 'next / head'
importer une mise en page à partir de '../layout/layout'
importer {ProxyContext} de '../context/proxy-context'

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

    revenir (
        
            
                 Non disponible 
            

            

Désolé. Le produit n'est pas disponible en {countryName}

Cliquez pour vous inscrire à la liste d'attente

) } export par défaut indisponible

 page non disponible

pages / abuse.js :

 import Réagissez de 'réagir'
importer Head de 'next / head'
importer une mise en page à partir de '../layout/layout'

const Abuse = () => (
    
        
             Abus 
        

        

Désolé! TOR Visiteurs non autorisés

Même si nous respectons la vie privée, nous préférons nous protéger des utilisateurs qui abusent des réseaux de protection de la vie privée

) défaut d'exportation

 page d’abus

Maintenant que nous avons implémenté toutes nos pages de destination, nous devons les rediriger automatiquement. Passez à la section suivante.

Déviation du trafic vers des pages de destination appropriées

Pour effectuer la redirection dans Next.js, vous devez utiliser le crochet useRouter du suivant / routeur. pour accéder au composant du routeur . Nous allons utiliser la fonction router.replace () pour effectuer la redirection. Il faut définir deux actions de redirection différentes:

  1. La ​​première redirection sert à bloquer le trafic Tor et à être redirigé vers la page «abus».
  2. La ​​deuxième redirection est destinée à détourner le trafic vers «l’atterrissage» ou le « non disponible ”.

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

 import {useRouter} à partir de 'next / router'

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

  // Déclarer le routeur
  const routeur = useRouter ();

  // Rediriger si le type de mandataire est TOR
  useEffect (() => {
    if (proxy.proxyType == 'TOR') {
      router.replace ('/ abuse')
    }
  }, [proxy])

  // redirection en fonction du pays du visiteur
  const {countryName} = proxy
  useEffect (() => {
    if (countryName! = 'Nowhere' && newProxy.proxyType! == 'TOR') {
      redirectPage (router, countryName)
    }
  }, [proxy]);

  // ...
}

const redirectPage = (router, countryName) => {
  laissez redirectPage;
  commutateur (nom de pays) {
    case 'Kenya': // Remplacez par le nom de votre pays
      redirectPage = '/ landing'
      Pause
    cas 'Royaume-Uni':
      redirectPage = '/ landing'
      Pause
    défaut:
      redirectPage = '/ indisponible'
  }
  router.replace (redirectPage)
}

Dans la fonction 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 limiter le nombre de pays, car le nombre de pays pris en charge par un service proxy est limité. En parlant de test, nous devons d’abord déployer notre application.

Conseil: Si vous souhaitez tester manuellement sans déployer, associez simplement la constante ipAddress à une adresse IP d’un autre pays. Vous pouvez également tester les adresses IP TOR en sélectionnant l'une de cette liste d'adresses IP Tor .

Déploiement de notre application Next.js

Le moyen le plus simple et le plus rapide de déployer notre application Next.js sur une production. Le serveur utilise la plate-forme de déploiement sans serveur de Zeit . Tout ce que vous avez à faire pour commencer est d'installer leur Now CLI . Il vous suffira de vérifier votre adresse électronique pour utiliser le service gratuit.

Si nous déployions notre application maintenant, elle fonctionnerait comme prévu. Cependant, elle atteindra la limite de 20 crédits gratuits, car notre application est conçue pour utiliser la clé de démonstration si nous n’avons pas spécifié de clé API. Pour télécharger notre clé maintenant, exécutez simplement la commande suivante:

ajoutez maintenant les secrets NEXT_SERVER_IP2PROXY_API .

Pour en savoir plus sur la gestion des variables d'environnement et des secrets sur le tableau de bord Zeit cliquez 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 construction, puis le déploiera sur les serveurs de Zeit. L'ensemble du processus devrait durer moins d'une minute. L'URL du serveur de production sera automatiquement copié dans votre presse-papiers. Ouvrez simplement un nouvel onglet de votre navigateur et collez l'URL. Vous devriez voir quelque chose de similaire à ci-dessous:

 production deploy

Test du site avec des services proxy gratuits

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

 hma formulaire de procuration

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

[1965- Atterrissage du proxy hma

Tout autre pays redirigera vers la page “indisponible”.

 Proxy hma indisponible

Test du site avec le navigateur Tor

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

 pour le test du navigateur

Conseil: Si vous rencontrez des difficultés pour installer Tor sur votre ordinateur, il est 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 offre des versions de base de données de leurs services Web. Il se présente sous la forme d'un fichier CSV pouvant être importé dans le système de base de données de votre choix. 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 permettre une réponse plus rapide. Notez que lorsque vous achetez une base de données, celle-ci 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 vers un service de cloud tel que MongoDb ou FaunaDb . Cependant, le déploiement de votre base de données sur un serveur différent annule les avantages d'une base de données locale. Ma recommandation est d'utiliser les conteneurs Docker pour conditionner et déployer votre application et votre base de données sur le même serveur ou centre de données afin de gagner rapidement en vitesse. vers les pages de destination pertinentes en fonction du pays où ils parcourent. Grâce aux informations fournies par les services IP2Location, vous pouvez aller plus loin dans votre site Web en:

  • proposant différents coupons ou offres à différents endroits géographiques
  • mettant en œuvre la détection de fraude par carte de crédit en comparant l'emplacement du visiteur avec l'adresse géographique réelle du titulaire. .

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 en une seule application, vous pouvez consulter ce projet que j'ai déjà construit et qui va vous montrer comment faire.




Source link