Le diagramme ci-contre donne une idée simplifiée de la suite des échanges entre les 3 pôles d’un flux de type Serveur à serveur.
Cliquez sur l’image pour l’agrandir
Ce flux n’identifie pas l’utilisateur final, qui n’entre pas en ligne de compte. Il est donc utile pour effectuer des tâches requérant un accès de l’application à des ressources protégées hors du contrôle de l’utilisateur final.
Du côté du client
Voici un exemple en PHP pour SPIP 3.1 :
SPIP
- /**
- * Interface avec OAuthSD, Flux d'autorisation de serveur à serveur
- * (Client Credentials Grant).
- * Cette fonction interroge une API protégée et retourne le résultat au format JSON.
- * Si l'API refuse l'accès, une nouvelle demande de jeton est lancée automatiquement.
- *
- * @param mixed $request : URI de l'appel à l'API REST
- * @return mixed string, bool : Résultat de la requête au format JSON ou false en
- * cas de refus d'accès.
- *
- * Auteur: B.Degoy DnC https://degoy.com/#dnc_conteneur_contact
- * licence GNU/GPL v3
- *
- */
- function ProtectedApi_GET_auto( $request ) {
- }
- include_spip('inc/headers');
- include_spip('inc/distant');
- if ( !$token ) $token = $_SESSION['oauth_access_token'];
- // Interroger la ressource protégée
- $request_response = recuperer_url($request . "&token=$token");
- if ( (int)$request_response['status'] == 200 ) {
- // Ok
- return $request_response['page'];
- } elseif ( (int)$request_response['status'] == 401
- OR (int)$request_response['status'] == 403 ) {
- // Pas le droit d'accéder à cette ressource.
- // Commencer par vérifier le jeton
- $url = "http://oa.dnc.global/oauth/resource.php?access_token=" . $token;
- $resource_response = recuperer_url($url);
- $status = (int)$resource_response['status'];
- $error = $page['error'];
- $error_description = $page['error_description'];
- switch( $status ) {
- case 200 :
- // Si le jeton était valide, ne pas boucler!
- return false;
- break;
- default :
- // Demander un nouveau jeton et recommencer
- return _replay( $request );
- break;
- }
- return false;
- }
- } else {
- // Demander un nouveau jeton et recommencer
- return _replay( $request );
- }
- }
- function _replay( $request ) {
- if ( $token = GetToken() ) {
- $_SESSION['oauth_access_token'] = $token;
- $_GET['token'] = $token;
- ProtectedApi_GET_auto( $request );
- } else return false;
- }
- /**
- * Demander un nouveau jeton d'accès au serveur OAuth
- * Flux Client Credentials Grant
- *
- * Auteur: B.Degoy DnC https://degoy.com/#dnc_conteneur_contact
- * licence GNU/GPL v3
- *
- */
- function GetToken() {
- // Interroger Token
- $jeton = '';
- $url = 'http://oa.dnc.global/token.php';
- 'method' => 'POST',
- 'grant_type' => 'client_credentials',
- 'client_id' => 'radar',
- 'client_secret' => '01fc4587ab1c23ff456e448dab18327a',
- )
- );
- $res = recuperer_url( $url, $options );
- $token = $page['access_token'];
- }
L’utilisation de la fonction est très simple.
La fonction retourne un objet JSON représentant la réponse, que l’on peut facilement transformer en Array PHP :
PHP
- // Le nom de l'application cliente
- // La requete
- $req = "http://chemindeleau.com/?page=gis.json&pt=1";
- echo '<h3>Résultat de : ' . $req . '</h3><br/>';
- $api_result = ProtectedApi_GET_auto( $req );
- if ( $api_result == false ) {
- $api_result = "Erreur !";
- } else {
- echo '<pre>';
- echo '</pre>';
- }
Du côté du serveur de ressource
Voici un exemple de serveur de ressource simple :
SPIP
- #CACHE{2}
- [(#REM)
- Liste de Tagazd en JSON.
- Nécessite les plugins geobase et gis.
- Exemple d'appel:
- http://xxx.com/?page=gis.json&pt=nn
- où nn est l'id du point dans la table gis.
- Copyright (c) 2001-2016
- Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James
- Copyright(c) 2013-2016 DnC
- Auteur: B.Degoy DnC https://degoy.com/#dnc_conteneur_contact
- Licence GNU/GPL v3
- ]
- <?php
- function oauth_authorize($accesstoken) {
- // Interroger OAuth Server by DnC
- include_spip('inc/distant');
- // Vérifier le jeton d'accès (access token)
- $url = "https://oa.dnc.global/oauth/resource.php?access_token=" . $accesstoken;
- $res = recuperer_url($url);
- if ( (int)$res['status'] === 200 ) {
- return true ;
- }
- }
- return false;
- }
- if ( !(bool)@oauth_authorize(_request('token')) ) {
- }
- // Si le jeton est valide, demander à SPIP d'émettre le contenu au format JSON :
- ?>
- #HTTP_HEADER{Content-Type: application/json; charset=#CHARSET}
- [<BOUCLE_docp(DOCUMENTS){gis}{', '}{distancefrom #ENV{pt}, <=, 100}{extension IN png,jpg,gif,html}{par distance}{0,#ENV{limit,100}}>
- [(#ARRAY{
- id,#ID_GIS,
- titre,#TITRE,
- distance,[(#DISTANCE|format_kmm)],
- quadrant,[(#ENV{pt,1}|quadrant{#ID_GIS})],
- lat,#LAT,
- lon,#LON,
- url,#URL_SITE_SPIP/?page=photo&id_document=#ID_DOCUMENT,
- }|json_encode)]
- </BOUCLE_docp>]
La première partie du code en PHP valide le jeton d’accès auprès du serveur OAuthSD. En cas d’échec, l’exécution est interrompue et le serveur retourne le code HTTP 401 (Non autorisé) et un contenu vide.
Dans la deuxième partie "écrite en SPIP", vous remarquerez comme SPIP permet de générer facilement toute sortes de contenus à partir de données diverses. Nous avons ici une jointure entre des documents et des points géographiques retournée au format application/json.
Lancer un test
Ce test met en œuvre le code présenté ci-dessus.
Les rôles sont les suivants :
application cliente et utilisateur final : radar (r.dnc.global),
serveur de ressource (données protégées) (API Rest) : chemindeleau.com,
serveur d’authentification : oa.dnc.global,
Lancer le test get-gis-data_exemple
Lors de la demande de vos login et mot de passe, si vous ne voulez pas vous inscrire sur ce serveur en tant qu’utilisateur, vous pourrez utiliser les identifiants suivants :
E-mail or pseudo : bebert
Password : 012345678
L’application cliente demande au serveur les points situés à moins de 100km autour du point pt=1, qui correspond à la "Fontaine chaude" de Bourbonnes-les-bains. Le résultat est ordonné par distance croissante.
Vous obtiendrez la réponse suivante :