Carnet Wiki

Se connecter à un compte SPIP depuis un autre programme PHP


-  Issu de https://discuter.spip.net/t/180501, https://discuter.spip.net/t/192452 et autres
-  Voir aussi Appeler SPIP depuis un autre programme PHP

Via les headers Basic Auth

L’autorisation d’une requête de l’API peut se gérer par HTTP Basic
cf Authorization - HTTP (MDN) et Authentification HTTP (Wikipédia)

Le plugin http vérifie que le login et mdp, tels que fournis par l’authentification http Basic, correspondent bien à des comptes SPIP. Ou plutôt en fait : c’est SPIP qui vérifie que les credentials fournis par l’authentification Http Basic correspondent au login et mot de passe d’un utilisateur inscrit, et le plugin http bénéficie de cette vérification en amont de son exécution.

-  Du côté du requêteur, il faut ajouter une entête genre
’Authorization: Basic ’.base64_encode(“$auth_user:$auth_password”).“\r\n” ([EDIT] yavait une erreur)
-  avec le login et mot de passe SPIP préalablement communiqués
-  Du côté du serveur, SPIP se charge de tout et autorise le service de la requête

Voir aussi : https://discuter.spip.net/t/180506

Se connecter « comme l’API SPIP »

Question « J’utilise le plugin Spip Headless comme base pour l’api. Spip gère entièrement les contenus et c’est vraiment parfait associé au front end basé sur Vuejs que j’ai développé. Pour utiliser le plugin Accès Restreint et Spip Zone, l’utilisateur doit être authentifié. L’objectif c’est que j’associe cette authentification aux requêtes que j’envoie, mais que côté serveur aussi les requêtes soient filtrées en fonctions des droits de l’utilisateur. »

Actuellement, un code simplifié permet de se connecter à un SPIP 4 pour un usage extérieur sans passer par l’API SPIP. Ça reprend donc partiellement ce que fait SPIP dans son API mais uniquement l’authentification spip, ça ne prend pas en charge les vieux mots de passe d’anciennes versions de SPIP et ça ne fait pas « tourner » les clés.

// Extraire la chaine représentant le JSON du fichier /config/cles.php
// voir /ecrire/inc/flock.php : lire_fichier_securise
$clesFile = '{"secret_du_site":"xxxxxxxxxxxxxx","secret_des_auth":"yyyyyyyyyyyyyyyyyyyy"}';

// Décoder cette chaine en JSON
$clesJson = json_decode($clesFile, true);

// Décoder les valeurs des clés
$cles = array_map('base64_decode', $clesJson);

// Récupérer la clé secrete
$secretKey = $cles['secret_des_auth'];

$login = 'l-identifiant';
$password_clair = 'le-mdp-en-clair';

// Récupéré dans la table 'spip_auteurs', colonne 'pass'
$password_hash = 'le-password-crypte'; 

$pass_poivre = hash_hmac('sha256', $password_clair, $secretKey);
$isAuth = password_verify($pass_poivre, $password_hash);

if ($isAuth) {
    // authentifé !
}

Cette manière de faire n’est toutefois pas durable car elle ne marchera plus si le code SPIP évolue. Pour faire une vérification manuelle du login+pass de quelqu’un de manière pérenne, il faut utiliser l’API auth ainsi que l’indique @cerdic :

include_spip('inc/auth');
$auteur = auth_identifier_login($login, $pass, '', true);
if ($auteur) {
    // c'est bien le login/pass d'un auteur qui est décrit dans le tableau $auteur
} else {
    // c'est personne de connu
}

C’est ce qui est fait dans la partie suivante, avec un exemple de code plus complet.

Continuer à naviguer connecté après une première authentification

( Issu de https://discuter.spip.net/t/192452)

Une fois authentifié par SPIP, si on veut permettre de poursuivre une navigation sur le site en continuant à être logé (par exemple pour naviguer dans des parties à accès restreint), il faut entièrement loger l’utilisateur.

Francis confie son fichier test_connexion.php :

<?php
if(!isset ($_SESSION)){
   session_start();
} 

use function SpipLeague\Component\Kernel\param;

require_once __DIR__ . '/vendor/autoload.php';

$ecrire = param('spip.dirs.core');

include_once $ecrire . 'inc_version.php';

// Inclure l'initialisation de SPIP
include_once("config/ecran_securite.php");
include_spip($ecrire .'inc/session');
include_spip($ecrire .'inc/headers'); // Charge la fonction redirige_url()
include_spip($ecrire .'inc/utils'); // Charge la fonction _request()
include_spip($ecrire .'inc/sql'); // Charge les fonctions SQL comme sql_getfetsel()
//include_spip( $ecrire . 'inc/auth.php');
require_once('ecrire/inc/auth.php');

$article = 13; 
$username = 'monLogin';
$pass = 'monPassword';

//Vérification de l'existence du compte utilisateur dans SPIP
$auteur = auth_identifier_login($username, $pass, '', true);
if ($auteur) {
    // c'est bien le login/pass d'un auteur qui est décrit dans le tableau $auteur
    echo("<br>Le demandeur a été authentifé !</br>");
    // Initialiser la connexion SQL
    spip_connect();
} else {
    // c'est personne de connu
    echo("<br>Inconnu !<\br>");
}
$id_auteur = $auteur['id_auteur'];
//var_dump($auteur);

// Vérifier et établir la session
if ($id_auteur) {
   // Créer une session pour cet utilisateur
   session_set("id_auteur", $id_auteur);
   session_set("login", $username);
   session_set("statut", '6forum');
   // L'utilisateur est déjà connecté, rediriger vers l'article
    $url = url_de_base() .  './?article'.$article;

    header("Location: $url");

// Rediriger ou continuer le script
   echo "Connexion réussie ! ID auteur : " . $id_auteur;
} else {
   echo "Échec de la connexion : login ou mot de passe incorrect.";
}

On se connecte avec curl par la page de connexion de spip, si authentification valide, on récupère les cookies et après le token nécessaire.

$fields = [
    'page' => 'connexion',
    'formulaire_action' => 'login_public_page',
    'formulaire_action_args' => ''// generated data by SPIP,
    'formulaire_action_sign' => '',
    'var_login' => $_POST['login'] ?? '',
    'password' => $_POST['password'] ?? ''
];

$urlLogin = "https://" . $_SERVER["HTTP_HOST"] . "/spip.php?page=connexion";
$urlLogout = "https://" . $_SERVER["HTTP_HOST"] . "/spip.php?action=logout&logout=public";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $urlLogin);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '');  // Where to save cookies after the request, but I don't save the file, I get cookie "on the fly"
curl_setopt($ch, CURLOPT_COOKIEFILE, ''); // Where to read cookies from before the request
$response = curl_exec($ch);

$cookies = curl_getinfo($ch, CURLINFO_COOKIELIST);
curl_close($ch);
// handle $cookies
// next code
JLuc - Mise à jour :8 September 2025 at 15:34