web-dev-qa-db-fra.com

Comment configurer correctement un proxy inverse avec Apache, à utiliser pour AJAX interdomaine?

Devoir développer une application Web qui dépend dans le même temps d'une API, mais ne peut pas résider dans le même domaine que l'API elle-même, il est assez difficile de contourner la "politique d'origine" lors de la création de requêtes HTTP asynchrones. (AJAX). À un moment donné, il m'a été recommandé d'installer WAMP sur mon ordinateur (sous Windows 7) et de configurer un proxy inverse avec Apache . La même personne m'a donné les directives Apache ci-dessous que j'ai ajoutées au fichier httpd.conf, après m'avoir dit de créer un alias pour l'IP 127.0.0.1 nommédev, dans le fichier à c:\windows\system32\drivers\etc\hosts (ce que j'ai fait):

LoadModule headers_module modules/mod_headers.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule ssl_module modules/mod_ssl.so

Listen 127.0.0.1:8080
ProxyRequests off

<Proxy *>
                Order deny,allow
                Deny from all
                Allow from 127.0.0.1
</Proxy>

<VirtualHost dev:8080>
                ProxyPass / https://app.somesite.com:5002/
                ProxyPassReverse / https://app.somesitecom:5002/
                ProxyPassReverseCookieDomain app.somesite.com dev
                Header edit Location ^https://dev(:8080)?(.+)$ http://dev$1$2
                Header edit Set-Cookie "(^.+); secure; HttpOnly$" "$1; HttpOnly"
                SSLProxyEngine on
    SSLProxyVerify none
</VirtualHost>

Étant donné que je suis un novice en matière de configuration de serveurs, j'ai simplement collé les directives et, heureusement, le proxy a fonctionné. Il renvoie la réponse correcte de l'API lorsque j'utilise la barre d'adresse du navigateur pour accéder, par exemple, à http://dev:8080/a/w/currencies.

Malheureusement, une requête AJAX à la même URL (code ci-dessous) fait que Chrome me donne l'erreur XMLHttpRequest cannot load http://dev:8080/a/w/currencies. Origin http://dev is not allowed by Access-Control-Allow-Origin..

$.ajax({
    url: "http://dev:8080/a/w/currencies",
    type: "GET",
    dataType: "json",
    data: {

    },
    success: function(data){
        console.log(data);
    }
}); 

Alors, que faut-il encore faire pour que cette procuration fonctionne avec AJAX? On m'a dit quelque chose à propos d'une directive alias, mais pas assez précise et claire, cela n'avait donc aucun sens pour mon cerveau inexpérimenté.

PS: De plus, on m'a dit "le problème est que vous obtenez les fichiers de dev: 80 et ajaxing en dev: 8080". Compte tenu de mon inexpérience, cela n'a pas beaucoup de sens.

10
Andrei Oniga

Vous avez un serveur avec une adresse IP publique et Apache s'exécute sur celui-ci. Maintenant, vous souhaitez héberger vos applications sur un réseau local et les rendre accessibles sur Internet. L'important est que ces applications fonctionnent toujours sur les machines sur un réseau local.

                           |--------------192.168.1.3
                           |            (internal3.example.com)
                           |
                           |--------------192.168.1.4
                           |            (internal4.example.com)
  (Public IP )             |
            A--------------|
(reverse proxy server)     |
  (192.168.1.25)           |
example.com                |
                           |--------------192.168.1.1
                           |            (internal1.example.com)
                           |
                           |--------------192.168.1.2
                           |            (internal2.example.com)

J'utilise Ubuntu pour héberger Apache (définition vhost) dans le cas de systèmes basés sur Debian, la définition des sites Web est effectuée sur

/etc/Apache2/sites-enabled/*.conf

où * conf correspond à

internal1.conf internal2.conf internal3.conf internal4.conf

La définition de chacun de ces sites sera la suivante

/etc/Apache2/sites-enabled/internal1.example.conf

  ServerAdmin webmaster@localhost
  ServerName internal1.example.com
  ProxyRequests off
  <proxy *>
  Order deny,allow
  Allow from all
  </proxy >
  ProxyPass / http://192.168.1.1/
  ProxyPassReverse / http://192.168.1.1/ </VirtualHost >

/etc/Apache2/sites-enabled/internal2.example.conf

<virtualhost *:80>

      ServerAdmin webmaster@localhost
      ServerName internal2.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.2/
      ProxyPassReverse / http://192.168.1.2/
</VirtualHost >

/etc/Apache2/sites-enabled/internal3.example.conf

<virtualhost *:80>

      ServerAdmin webmaster@localhost
      ServerName internal3.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.3/
      ProxyPassReverse / http://192.168.1.3/
</VirtualHost >

/etc/Apache2/sites-enabled/internal4.example.conf

      ServerAdmin webmaster@localhost
      ServerName internal4.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.4/
      ProxyPassReverse / http://192.168.1.4/
</VirtualHost >

Remarque dans toutes les définitions vhost ci-dessus, j'ai supprimé les options de fichiers journaux . Si vous vous appliquez à un serveur de production, ajoutez-les à chacun des fichiers vhost . Ci-dessus est simplement un exemple clair comme cela peut fonctionner ... Je lance une configuration très complexe d’Apache, ce qui est écrit ci-dessus n’est donc qu’un petit exemple pour vous aider.

Maintenant, venir à Ajax une partie de votre question

en chrome, appuyez sur Ctrl + Maj + I pour voir exactement où l'application est cassée, Cela vous donnera un indice, ( émettez la demande à partir d'une machine différente de celle sur laquelle vous développez l'application Web ) Si vous pouvez également consulter les journaux Apache si la requête de la page http://sample contenant aji api a effectivement atteint votre serveur Apache, ce qui vous donnera une indication supplémentaire, si le proxy transfère correctement votre requête, envoyez les en-têtes HTTP à l'aide de outil dans firefox comme live_http en condition quand il n'y avait pas de requête et la condition quand la requête était faite par l'application de cette façon en observant les en-têtes on peut vous aider si la requête a atteint le serveur derrière le proxy inverse, vérifiez aussi les logs du serveur qui exécute un proxy inverse si la demande de Web l'a atteinte ou non et si la demande a atteint l'URL demandée. Cela vous donnera un indice,

et à des fins de développement dans vos fichiers .conf, désactivez les règles de réécriture pendant un certain temps, faites-les une à une.

10
Registered User

Le problème ici est que le navigateur essaie de vous protéger contre le pwned par du javascript aléatoire placé sur une page Web. Si cela permettait à tout le javascript de s'exécuter dans le même contexte, vous perdriez vos cookies de sessions Facebook ou certaines autres données au profit des malfaiteurs.

Dans ce cas, le coupable pourrait être quelque chose d'aussi simple, car Chrome ne considère pas «dev» comme un nom de domaine pleinement qualifié, de sorte qu'il échouera au même test Origine. Une autre raison pourrait être qu’à un moment donné, vous obtenez des éléments de app.somesite.dev et que vous envoyez des demandes à «dev».

Les serveurs ne s’intéressent pas à ce qu’ils envoient et c’est le navigateur dont vous avez besoin pour vous permettre de croire que tout provient du même hôte.

  1. Je remplacerais "dev" dans le fichier hosts par dev.example.com 127.0.0.1
  2. Je voudrais m'assurer que tout ce qui sort du proxy Apache fait uniquement référence à dev.example.com, peu importe le serveur sur lequel il provient.
  3. Utilisez uniquement dev.example.com dans votre code

Si tout le reste échoue, vous pouvez ajouter un en-tête HTTP 'Access-Control-Allow-Origin: *' pour autoriser toute origine, mais je ne l'utiliserais que dans les environnements de développement.

PS. Même si vous obtenez le code javascript d’exemple.com:80, javascript ne peut même pas appeler exemple.com:443, ni le code javascript de exemple.com ne permet pas de convertir xmlhttprequests en dev.example.com.

1
user2977023

sur 127.0.0.1, votre code html devrait être:

$.ajax({
    url: "http://127.0.0.1/a/w/currencies",
    type: "GET",
    dataType: "json",
    data: {
    },
    success: function(data){
        console.log(data);
    }
}); 

sur 127.0.0.1, votre conf Apache devrait être:

...

<VirtualHost dev:8080>
            ...
            ProxyPass / https://app.somesite.com:5002/
            ProxyPassReverse / https://app.somesitecom:5002/
            ...
</VirtualHost>

dans ce cas, votre navigateur ne sera pas interdomaine, car votre URL et votre ajax utilisent le même domaine. Mais exactement, demande ajax https://app.somesite.com:5002/ , je ne le fais pas savoir si c'est un proxy inverse, mais il semble que le travail pour moi. Essaye :)

0
HornedReaper