Une fonction pour tout simplifier !

, par B. Degoy

Du côté d’une application cliente, utiliser l’authentification OAuth pour interroger une API HTTP REST peut se réduire à une simple fonction.

Nous sommes dans le cas du flux Autorisation via un code (Authorization Code Grant).

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 Autorisation via un code. La fonction ci-dessous correspond à la ligne "Client App". Le rafraîchissement du jeton d’accès qui apparaît dans le code a été omis dans le diagramme pour simplifier. Cliquez sur l’image pour l’agrandir
<clear1>

Voici un exemple en PHP pour SPIP 3.1 :
SPIP

<?php
/**
* Interface avec OAuthSD, Autorisation via un code (Authorization Code 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 demande d'authentification de l'utilisateur final 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.
*/
function ProtectedApi_GET_auto ( $request ) {

    include_spip('inc/headers');
    include_spip('inc/distant');

    $token = $_SESSION['oauth_access_token'];
    if ( !$token  ) {
        if ( isset($_GET['token']) ) {
            $token = $_GET['token'];
        }
    } 

    if ( !empty($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 ) {

            // 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'];
            $page = json_decode($resource_response['page'], true);
            $error = $page['error'];
            $error_description = $page['error_description'];  

            switch( $status ) { 

                case 200 :
                    // Le jeton était valide,ne pas boucler!
                    return false;
                    break;

                case 401 : 

                    if ( $error == 'expired_token' ) {
                        // Rafraîchir le jeton expiré 

                        // Interroger Token
                        $options = array(
                            'methode' => 'POST',
                            'datas' => array(
                                'grant_type' => 'refresh_token',
                                'refresh_token' => $_SESSION['oauth_refresh_token'],
                                'client_id' => 'chemindeleau',
                                'client_secret' => '01fc4587ab1c23ff456e448dab18327a', 
                            ),      
                        );

                        $url = "http://oa.dnc.global/oauth/token.php";
                        $refresh_response = recuperer_url($url,$options);
                        $refresh_status = (int)$refresh_response['status'];

                        if ( $refresh_status == 200 ) {

                            // Enregistrer le jeton d'accès et recommencer
                            $page = json_decode($refresh_response['page'], true);
                            $_SESSION['oauth_access_token'] = $page['access_token'];
                            return ProtectedApi_GET_auto ( $request); // réentrer

                        } else 
                            // Demander une nouvelle authentification
                            Authenticate();

                    } else return false;

                    break;

                default :

                    // Demander une nouvelle authentification
                    Authenticate();

            }
            return false;
        }
    } else {

        // Demander une nouvelle authentification
        Authenticate();

    }

}

/**
* Demander une nouvelle authentification au serveur OAuth
*/
function Authenticate() {
    
    // Sécurité : Générer un ID de session nouveau à chaque demande d'autorisation 
    @session_regenerate_id();
    
    // Dire à Callback où il faudra reprendre après authentification
    $_SESSION['oauth_again'] = $_SERVER['REQUEST_URI'];

    // Interroger Authorize
    $url = "https://oa.dnc.global/oauth/authorize.php?response_type=code&client_id=" . APPNAME . "&state=" . session_id();
    redirige_par_entete($url);    

}

 

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 :

// Le nom de l'application cliente
define ( 'APPNAME', 'testrpc3' );
// Requete
$request = "https://r.dnc.global/http.api/collectionjson/gis/27";
// Afficher l'array obtenu
echo print_r( json_decode( ProtectedApi_GET_auto ( $request ) ) , true );

Lancer un test

Dans ce test, les rôles sont les suivants :
– application cliente : chemindeleau,
– serveur de données protégées : API Rest de Radar,
– serveur d’authentification : oa.dnc.global,
– utilisateur final : vous.

Lancer le test

Vous devrez cliquer sur "Inscrivez-vous ici" pour être inscrit comme client final sur le serveur d’autorisation. Rappel : nous ne divulguons pas les E-mails.

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