Page 1 sur 1

Authentification Web Service

Posté : 27 janv. 2016, 00:30
par Mohi
Bonjour,

J'ai réalisé un simple service web (en SOAP) qui renvoie Hello + la chaîne passée en paramètre de l'URL. J'ai suivi ce tuto et ca fonctionne bien : https://www.youtube.com/watch?v=e_7jDqN2A-Y

J'ai un fichier service.php qui est appelé et qui fait appel à client.php et server.php.

Je souhaiterais ajouter une méthode basic d'authentification avec HTTPS + filtrage sur l'IP.

Je ne sais pas du tout comment ça marche, quelqu'un pourrait-il m'orienter pour mettre en place l'authentification ou m'indiquer un tuto ?

Merci de votre aide !

Re: Authentification Web Service

Posté : 27 janv. 2016, 10:43
par @rthur
Bonjour,

1) Pour de l'authentification basique, il y a un tuto dans la doc PHP : http://php.net/manual/fr/features.http-auth.php

2) Pour le HTTPS, ce n'est pas du PHP mais de la configuration serveur donc il faut que tu demandes cela à ton hébergeur.
A noter qu'il s'agit dans 99% des cas d'une option payante chez ton hébergeur, même si certaines initiatives type Let's encrypt peuvent fournir des certificats gratuits.
Si c'est juste pour un test, le plus simple c'est de passer par Cloudflare à qui tu vas déléguer la gestion de ton domaine et qui va servir de proxy en quelque sorte pour ton site et qui te fournira du HTTPS gratuitement d'un simple clic dans la console d'admin (c'est gratuit).

3) Pour le filtrage par IP, c'est très simple, l'IP du visiteur qui charge ta page est dans la variable $_SERVER['REMOTE_ADDR']
Par contre si tu passes par Cloudflare, cette variable correspondra à l'IP des serveurs de Cloudflare puisqu'il va jouer un rôle d'intermédiaire. Derrière Cloudflare, la véritable adresse IP du visiteur est dans la variable $_SERVER["HTTP_CF_CONNECTING_IP"].
Du coup il est préférable d'ajouter le bout de code ci-dessous en début de ta page et ensuite de continuer d'utiliser $_SERVER['REMOTE_ADDR']
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
  $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
}

Re: Authentification Web Service

Posté : 27 janv. 2016, 11:14
par mohi
Bonjour,

Merci pour ta réponse.

Après plus d'investigation, je me rends compte que j'ai peut-être mal fait mon Web Service car je n'ai pas de WSDL. J'ai un client.php un server.php et un service.php qui est appelé.

Penses-tu qu'il est préférable de faire un WSDL ? Je souhaiterais retourner ma réponse en format XML. Si oui, aurais-tu un tuto à me conseiller ?

1°) Pour l'authentification, je souhaiterais passer le login/mdp dans un header. Connais-tu un tuto pour ca ?

2°) D'accord pour le HTTPS, je paye un serveur pour ça.

3°) Pour l'IP, j'ai fait un petit test en local qui affiche l'ip :

Code : Tout sélectionner

$ip = $_SERVER['REMOTE_ADDR']; echo $ip ;
Ca me retourne : "::1". Cette variable ne fonctionne pas en local ?


Pour être plus clair, voici mon code qui renvoi le nom d'une personne en fonction de son id :
client.php :

Code : Tout sélectionner

<?php class client{ public function __construct(){ $params = array('location' => 'http://localhost/webservice/server.php', 'uri' => 'urn://localhost/webservice/server.php', 'trace' => 1); $this->instance = new SoapClient(NULL, $params); //set the header $auth_params = new stdClass(); $auth_params->username = 'name'; $auth_params->password = 'password'; $header_params = new SoapVar($auth_params, SOAP_ENC_OBJECT); $header = new SoapHeader('codev', 'authenticate', $header_params, false); $this->instance->__setSoapHeaders(array($header)); } public function getName($name_array){ return $this->instance->__soapCall('getName', $name_array); } } $client = new client; ?>
server.php :

Code : Tout sélectionner

<?php class server{ private $con; public static function authenticate($header_params){ if($header_params->username == 'name' && $header_params->password == 'password') return true; else throw new SOAPFault('Wrong user/pass combination', 401); } public function __construct(){ $this->con = (is_null($this->con)) ? self::connect() : $this->con; } static function connect(){ $con = mysql_connect('localhost', 'root', ''); $db = mysql_select_db('soap', $con); return $con; } public function getName($id_array){ $id = $id_array['id']; $sql = "SELECT name FROM personne WHERE id = '$id'"; $qry = mysql_query($sql, $this->con); $res = mysql_fetch_array($qry); return $name_array; } } $params = array('uri' => 'webservice/server.php'); $server = new SoapServer(NULL, $params); $server->setClass('server'); $server->handle(); ?>
service.php :

Code : Tout sélectionner

<?php include './client.php'; $id= $_GET['id']; $id_array = array('id' => $id); echo "Hello " .$client->getName($id_array); ?>
Merci encore :)

Re: Authentification Web Service

Posté : 27 janv. 2016, 11:29
par @rthur
J'avais pas lu que tu faisais un webservice en SOAP, mon conseil, c'est si tu as le choix d'arrêter tout de suite et de faire ton webservice en REST.
Le SOAP est très clairement en perte de vitesse depuis plusieurs années.

Sinon tu peux récupérer tous les headers avec la fonction getallheaders
http://php.net/manual/en/function.getallheaders.php
Ca me retourne : "::1". Cette variable ne fonctionne pas en local ?
C'est bien ton adresse IP locale :-)
::1 signifie localhost en ipv6

Re: Authentification Web Service

Posté : 27 janv. 2016, 11:45
par mohi
Je n'ai malheureusement pas le choix mais merci du conseil :)

Donc pour toi, si tu devais faire un WebService en SOAP avec une authentification qui passe par le header et qui renvoi hello + la variable en paramètre, est-ce que cette façon de faire te parait propre/correcte ? (sans parler de l'IP pour l'instant)

service.php qui serait appelé par cette URL (en local) : http://localhost/webservice/service.php?name=1 et qui aurait en header login et password.

Code : Tout sélectionner

<?php include './client.php'; $name = $_GET['name']; $pass = ""; $login = ""; foreach (getallheaders() as $name => $value) { if($name == "password"){ $pass = $value; } if($name == "login"){ $login = $value; } } $client = new client($login, $pass); $name_array = array('name' => $name); echo "Hello " .$client->getName($name_array); ?>
client.php :

Code : Tout sélectionner

<?php class client{ public function __construct($login, $pass){ $params = array('location' => 'http://localhost/webservice/server.php', 'uri' => 'urn://localhost/webservice/server.php', 'trace' => 1); $this->instance = new SoapClient(NULL, $params); //set the header $auth_params = new stdClass(); $auth_params->username = $login; $auth_params->password = $pass; $header_params = new SoapVar($auth_params, SOAP_ENC_OBJECT); $header = new SoapHeader('codev', 'authenticate', $header_params, false); $this->instance->__setSoapHeaders(array($header)); } public function getName($name_array){ return $this->instance->__soapCall('getName', $name_array); } } ?>
server.php :

Code : Tout sélectionner

<?php class server{ public static function authenticate($header_params){ if($header_params->username == 'name' && $header_params->password == 'password') return true; else throw new SOAPFault('Wrong user/pass combination', 401); } public function getName($name_array){ return $name_array; } } $params = array('uri' => 'webservice/server.php'); $server = new SoapServer(NULL, $params); $server->setClass('server'); $server->handle(); ?>

Re: Authentification Web Service

Posté : 27 janv. 2016, 13:35
par @rthur
Donc pour toi, si tu devais faire un WebService en SOAP avec une authentification qui passe par le header et qui renvoi hello + la variable en paramètre, est-ce que cette façon de faire te parait propre/correcte ? (sans parler de l'IP pour l'instant)
Je ne connais pas suffisamment SOAP, mais il doit forcément y avoir un système d'identification ou des bests practices sur le sujet.