Travaux concernant l'intégration d'OpenID dans les services du CDS
Description du développement et mise en pratique
Afin de permettre l’accès à un service par
OpenID, j’ai, avec l’aide de deux librairies, créé un petit fichier permettant d’instancier facilement la mise en place de
OpenID de manière a ce que celui ci communique également avec notre propre BDD. Le tout utilise PHP et
JavaScript.
Tout le nécessaire est inclut dans le fichier zip. Pour l’installation, il suffit de toujours laisser les différents fichiers et dossier côte à côte comme ils le sont après avoir désarchivé. La configuration et l'instanciation ont lieu dans le fichier connexion PHP
Ci dessous le code source de ce fichier commenté pour la configuration.
Codes sources
Code source minimal :
<?php
require 'openid.php'; //on importe la librairie OpenID php utilisé
try {
$openid = new LightOpenID('localhost'); // On remplace ici 'localhost' par son nom de domaine
//le bloc if ci dessous instancie OpenID et c'est ici que l'on fait tous les traitements
if(!$openid->mode) { // Instantiation
if(isset($_POST['openid_identifier'])) {
$openid->identity = $_POST['openid_identifier'];
$openid->required=array('contact/email'); //--> en plus de l'identifiant unique, nous aurons accès à l'email de la personne
header('Location: ' . $openid->authUrl());
}
//Ci dessous le formulaire javascript/jquery permet à l'utilisateur de choisir comment il veux se connecter (par quel fournisseur d'OpenID)
?>
<link type="text/css" rel="stylesheet" href="css/openid.css" />
<script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="js/openid-jquery.js"></script>
<script type="text/javascript" src="js/openid-en.js"></script>
<script type="text/javascript">
$(document).ready(function() {
openid.init('openid_identifier');
});
</script>
<form action="/connexion.php" method="POST" id="openid_form">
<input type="hidden" name="action" value="verify" />
<fieldset>
<legend>Sign-in or Create New Account</legend>
<div id="openid_choice">
<p>Please click your account provider:</p>
<div id="openid_btns"></div>
</div>
<div id="openid_input_area">
<input id="openid_identifier" name="openid_identifier" type="text" value="http://" />
<input id="openid_submit" type="submit" value="Sign-In"/>
</div>
<noscript>
<p>OpenID is service that allows you to log-on to many different websites using a single indentity.
Find out <a href="http://openid.net/what/">more about OpenID</a> and <a href="http://openid.net/get/">how to get an OpenID enabled account</a>.</p>
</noscript>
</fieldset>
</form>
<?php
} elseif($openid->mode == 'cancel') { //Si l'utilisateur à interrompu la connexion auprès du fournisseur (Google, yahoo, etc.)
// inserer ici le traitement voulu
} elseif ($openid->validate()){ // Lorsque la connexion avec le fournisseur s'est bien déroulée
// L'utilisateur est connecté et on peux récupérer son identifiant unique (pouvant servir de password) et son mail (servant de login)
$identifiant=$openid->identity;
$returnVariables = $openid->getAttributes();
$mail=$returnVariables['contact/email'];
echo "SUCCESS";
//
// Il faut faire ensuite ici le nécessaire pour créer l'utilisateur dans la BDD s'il n'existait pas et surtout activer la session.
///
}
} catch(ErrorException $e) {
echo $e->getMessage();
}?>
Voici maintenant un exemple complet illustrant le code ci dessus. Celui-ci permet de détecter si une session est en cours, d'établir la connexion et les utilisateurs connectés peuvent écrire des messages dans la BDD :
<?php
session_start(); //Ici, pour se souvenir de l'utilisateur, on utilise les sessions php mais il est possible de faire autrement.
require 'openid.php'; //on importe la librairie OpenID php utilisé
try {
$openid = new LightOpenID('localhost'); // On remplace ici 'localhost' par son nom de domaine
if(isset($_POST['deco'])){ // Ce morceau de code s'exécute quand la personne a cliqué sur le bouton de déconnexion.
session_destroy();
echo "<meta http-equiv=\"refresh\" content=\"0\">";
}
if(isset($_POST['mess'])) { //lorsqu'une personne poste un message, on le met dans le BDD
if(isset($_SESSION['username'])){
try{
$bdd = new PDO('mysql:host=127.0.0.1;dbname=openid', 'root', 'pass');//avec ici '127.0.0.1' l'adresse ip de la BDD, 'openid' son nom, 'root' le nom d'utilisateur et 'pass' le mot de passe.
$query ="Insert into infos values('".$_SESSION['username']."','".$_POST['mess']."');";
$bdd->query($query);
}catch(Exception $e){
die('Erreur : '.$e->getMessage());
}
}else{
echo "Enregistrement impossible... La session a expiré...";
}
}
//le bloc if si dessous instancie OpenID et c'est ici que l'on fait tous les traitements
if(!$openid->mode) { // Instantiation
if(isset($_POST['openid_identifier'])) {
$openid->identity = $_POST['openid_identifier'];
$openid->required=array('contact/email'); //--> en plus de l'identifiant unique, nous aurons accès à l'email de la personne
header('Location: ' . $openid->authUrl());
}
if(isset($_SESSION['username'])){ //lorsqu'une session est déjà en cours, l'utilisateur peux écrire des messages
echo "Une session est en cours : (".$_SESSION['username'].")";
echo "<form action=\"/connexion.php\" method=\"post\"><input type=\"submit\" name=\"deco\" value=\"Se deconnecter\"></form>";
echo "</br></br><form action=\"/connexion.php\" method=\"post\"><input type=\"text\" name=\"mess\" /><input type=\"submit\" name=\"enre\" value=\"Enregistrer\"></form>";
try{
$bdd = new PDO('mysql:host=127.0.0.1;dbname=openid', 'root', 'pass'); //avec ici '127.0.0.1' l'adresse ip de la BDD, 'openid' son nom, 'root' le nom d'utilisateur et 'pass' le mot de passe.
$query ="select * from infos where username like '".$_SESSION['username']."';";
$reponse=$bdd->query("".$query);
echo "Liste des messages de l'utilisateur :</br>";
while($donnees=$reponse->fetch()){
echo "- ".$donnees['info']."</br>";
}
$reponse->closeCursor();
}catch(Exception $e){
die('Erreur : '.$e->getMessage());
}
}else{ // si aucun utilisateur est connecté, alors on affiche le formulaire javascript/Jquery pour que l'utilisateur choisisse sont fournisseur OpenID
echo "Aucune session en cours...";
?>
<link type="text/css" rel="stylesheet" href="css/openid.css" />
<script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="js/openid-jquery.js"></script>
<script type="text/javascript" src="js/openid-en.js"></script>
<script type="text/javascript">
$(document).ready(function() {
openid.init('openid_identifier');
});
</script>
</br>
<form action="/connexion.php" method="POST" id="openid_form">
<input type="hidden" name="action" value="verify" />
<fieldset>
<legend>Sign-in or Create New Account</legend>
<div id="openid_choice">
<p>Please click your account provider:</p>
<div id="openid_btns"></div>
</div>
<div id="openid_input_area">
<input id="openid_identifier" name="openid_identifier" type="text" value="http://" />
<input id="openid_submit" type="submit" value="Sign-In"/>
</div>
<noscript>
<p>OpenID is service that allows you to log-on to many different websites using a single indentity.
Find out <a href="http://openid.net/what/">more about OpenID</a> and <a href="http://openid.net/get/">how to get an OpenID enabled account</a>.</p>
</noscript>
</fieldset>
</form>
<?php
}
} elseif($openid->mode == 'cancel') { //Si l'utilisateur a interrompu la connexion auprès du fournisseur (Google, yahoo, etc.)
echo 'L\'utilisateur a interrompu la connexion.';
} elseif ($openid->validate()){ // Lorsque la connexion avec le fournisseur s'est bien déroulée
echo 'L\'utilisateur est connecte<br><br>';
$returnVariables = $openid->getAttributes();
echo 'Identifiant unique du compte : '.$openid->identity.'<br>'; //--> le code unique de l'utilisateur (pouvant servir de mot de passe)
echo 'Email : '.$returnVariables['contact/email'].'<br><br><br>'; //--> son adresse mail, servant lui de login
try{
// On instancie la BDD
$bdd = new PDO('mysql:host=127.0.0.1;dbname=openid', 'root', 'pass'); //avec ici '127.0.0.1' l'adresse ip de la BDD, 'openid' son nom, 'root' le nom d'utilisateur et 'pass' le mot de passe.
$query ="Select * from utilisateur where username like '".$returnVariables['contact/email']."';"; //On regarde ici si l'utilisateur existe djà dans notre BDD
$reponse=$bdd->query("".$query);
if($donnees=$reponse->fetch()){
echo '</br>L\'utilisateur est dans la BDD.';
}else{ //S'il n'existe pas, alors on l'ajoute dans notre BDD
echo '</br>L\'utilisateur n\'existe pas dans la BDD.';
echo '</br>Ajout....';
$bdd->query("Insert into utilisateur values ('".$returnVariables['contact/email']."','".$openid->identity."','".$returnVariables['contact/email']."');");
echo '</br>L\'utilisateur est bien enregistré dans la BDD !';
}
$_SESSION['username'] = $returnVariables['contact/email']; // On valide ici la session php pour reconnaitre l'utilisateur de page en page
$reponse->closeCursor();
?>
</br></br>redirection dans 5 secondes...
<meta http-equiv="refresh" content="5; URL=/connexion.php">
<?php
}catch(Exception $e){
die('Erreur : '.$e->getMessage());
}
}else{ // L'utilisateur a echoué son identification / OpenID a échoué
echo 'L\'utilisateur n\'est pas connecte<br>';
}
} catch(ErrorException $e) {
echo $e->getMessage();
}?>
Et voici le script utilisé pour la BDD dans l'exemple :
CREATE TABLE utilisateur(
username varchar(100),
email varchar(100),
id varchar(100) primary key
);
CREATE TABLE infos(
username varchar(100) references utilisateur(username),
info varchar(100),
primary key(username,info)
);