Bonjour à tous et à toutes !

Bon, dans le cadre du développement de mon site web ainsi que pour de futurs partenariats, je développe actuellement une API REST.

La méthode à laquelle j'ai pensé (puis dessiné), repose sur les sessions en PHP :

Nom : APIwithsessions.jpg
Affichages : 133
Taille : 166,2 Ko

Webservice Utilisateur : Personne/service qui dispose d'un enregistrement dans ma BDD avec un couple Username/MDP

Login : Reçois via $rs = json_decode(file_get_contents("php://input"), true); les données puis les compare aux enregistrements de la BDD et renvoi true ou false si l'utilisateur existe ou non. Ce même code crée une variable $session qu'il enregistre dans la BDD ET dans une variable de session $_SESSION['ssKey']


CONTROLLER :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
   	if(file_get_contents("php://input")):
    		$rs = json_decode(file_get_contents("php://input"), true);
    		if(!empty($rs['usn']) && !empty($rs['pwd'])):
    			logMeIn($rs['usn'],$rs['pwd']);
    		else:
    			echo json_encode(returnError(401));
    		endif;
    	else:
    		echo json_encode(returnError(401));
    		exit;
    	endif;
MODEL :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
   	function logMeIn($usn,$pwd){
    		global $bddo;

    		if(checkExistAccount($usn,$pwd) == true):
    			$session = createSessionKey();
    			$_SESSION['ssKey'] = $session;
    			$ip = $_SERVER['REMOTE_ADDR'];
    			$infos = array("session" => $session);
    			$bddo->exec("UPDATE api_customers SET apicSession=" . $bddo->quote($session) . ", apicIp=" . $bddo->quote($ip) . " WHERE apicUsername=" . $bddo->quote($usn) . " AND apicPassword=" . $bddo->quote($pwd));
    			echo json_encode(returnError(402, $infos));
    		else:
    			echo json_encode(returnError(401));
    			exit;
    		endif;
    	}
    	function checkExistAccount($usn,$pwd){
    		global $bddo;

    		$count = $bddo->query("SELECT COUNT(*) FROM api_customers WHERE apicUsername=" . $bddo->quote($usn) . " AND apicPassword=" . $bddo->quote($pwd))->fetchColumn();

    		if($count == 1):
    			return true;
    		else:
    			return false;
    		endif;
    	}
    	function createSessionKey(){
    		for($ligne=0;$ligne<30;$ligne++){
    			@$session.=substr('0123456789AZERTYUIOPMLKJHGFDSQWXCVBN',(rand()%(strlen('0123456789AZERTYUIOPMLKJHGFDSQWXCVBN'))),1);
    		}
    		return $session;
    	}
Soulignage rose : Tout ce qui est censé être sous session et donc recevoir le $_SESSION['ssKey']

Check Session : Page appelée partout (sauf sur le login), sur tous les modules de l'API qui contrôle et compare le $_SESSION['ssKey'] et l'enregistrement correspondant dans ma BDD. Détruit la session en cours si false, sinon, l'utilisateur peut continuer d'acter.

CONTROLLER :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
   	session_start();

    	if(checkSession($_SESSION["session"]) == TRUE):
    		$infos = array("session" => $_SESSION["session"]);
    		echo json_encode(returnError(402,$infos), true);
    	else:
    		echo json_encode(returnError(401), true);
    		session_unset();
    		session_destroy();
    		exit;
    	endif;

MODEL :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
   	function checkSession($session){
    		global $bddo;

    		$count = $bddo->query("SELECT COUNT(*) FROM api_customers WHERE apicSession=" . $bddo->quote($session))->fetchColumn();

    		if($count >= 1){return TRUE;}
    		else{return FALSE;}
    	}
J'ai testé ce système ce matin, le login fonctionne mais les variables de session ne se passent pas de page en page. Par exemple, un echo $_SESSION['ssKey'] dans la page index.php (avec session_start) renvoie une erreur

Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Undefined index: ssKey in C:\wamp64\www\api\v10\index.php on line 13

Voici le code coté client :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
    	function APIlogin($username, $password){
    		$url = "http://127.0.0.1/api/v10/login.json";
    		$post = '{"usn":"'.$username.'","pwd":"'.$password.'"}';
    		$ch = curl_init($url);
    		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    		curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 
    		$response = curl_exec($ch);
    		$decoded = json_decode($response, true);

    		return $decoded;
    	}

J'ai pensé à ce système car, même après avoir passé 1 semaine et demi à comprendre et à essayer diverses méthodes (dont les token et requêtes signées), je n'ai réussi à en adapter aucune.

Merci d'avance pour vos lumières, j’espère avoir été clair