Vérification de password en SPIP 4

Bonjour,
je suis en train de migrer le site sur le SPIP 3 vers le SPIP 4. Je suis bloqué sur la validation de « password ». Dans un module externe pour nos abonnés, nous utilisons la base ‹ auteurs › de SPIP pour gérer les connexions (notamment pour l’API mobile). L’encodage de mdp a changé, je ne trouve pas comment procéder à la vérification du couple de login-mdp.
La logique sur le site sur SPIP 3 :

$password = $_POST["password"];
$pass = //recuperer dans la table spip_auteurs via le login
$alea_actuel = //recuperer dans la table spip_auteurs
$password_encrypt = hash('sha256', ($alea_actuel . $password));
if ($password_encrypt == $pass) {
//le code
}

Merci d’avance pour votre aide !

Bonjour,

Il faut aller voir le code de ecrire/auth/spip.php · 4.3 · spip / spip · GitLab

Merci pour votre réponse ! Est-ce qu’on peut avoir un chemin direct vers \Password et \SpipCles, pour faire « include » sans utiliser « use » ?

tu peux peut être regarder du côté de prive/formulaires/login.php · master · spip / spip · GitLab

Je pense que j’ai trouvé, merci beaucoup.

Si tu veux poster ta solution, pour la postérité :slight_smile:

1 « J'aime »

Malheureusement, ma solution n’a pas marché, mon module externe (qui était écrite en php7) ne reconnait pas des ‹ include › de SPIP4. Par exemple quand j’inclue ‹ ecrire/auth/spip.php › et j’essaye d’utiliser la fonction ‹ auth_spip_dist › je reçois l’erreur « Uncaught Error: Call to undefined function sql_quote() ». ‹ sql_quote() › se trouve dans ‹ ecrire/base/abstract_sql.php › et est utilisé par ‹ auth_spip_retrouver_login › dans spip.php. Je n’ai pas trouvé encore la solution pour cela.

Faut faire require_once 'ecrire/inc_version.php'; (pour SPIP4)
Ou
require_once 'vendor/autoload.php'; (pour SPIP5)

include_spip('base/abstract_sql);` pour déclarer les fonctions SQL si ce n’est pas encore le cas là du coup.

Bonjour à tous, je suis un collègue de Vlad, nous sommes toujours bloqués avec l’inclusion des fonctions. En fait notre API n’est pas située dans les mêmes répertoires que les classes de spip et lorsqu’on essaie de les inclure, nous avons des erreurs de chemins qui remontent.

Afin de clarifier un peu les choses, notre API nous sert à authentifier des utilisateurs qui se sont inscrits sur le site, depuis une application mobile tierce.

L’API se trouve à la racine du site dans un sous répertoire.

Existe-t-il sinon une autre solution type API pour obtenir la validation du coup et récupérer un token utilisateur, ses informations de compte, son ou ses abonnements?

Merci d’avance.

PS : Sujet non résolu au passage.

Le plugin http Serveur HTTP abstrait - Plugins SPIP facilite la mise en place d’une API. La page appelée peut être interrogée par curl dans ton code et renvoyer ce que tu veux.

On a trouvé une solution. 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.
Cela marche pour nous :slightly_smiling_face:

1 « J'aime »

Ah c’est malin.
Voudriez vous présenter le code qui fait ça ?

1 « J'aime »

Oui, voici le code:

// ...some code...
$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

Quelques commentaires et questions :

« page » => « connexion »,
« formulaire_action » => « login_public_page »,
« formulaire_action_args » => «  »// generated data by SPIP,
« formulaire_action_sign » => «  »,
Ce code-là est hardcoder, je n’arrive pas le récupérer d’ici. Sans ce bout de code authentification ne passe pas. Si je comprends bien, « formulaire_action_args » est unique par serveur (?). Ça fait environs deux mois que je travaille avec le SPIP, je n’ai pas encore compris comment « formulaire_action_args » est généré. Je suis en train de creuser sur ce sujet, mais pour l’instant ça marche comme ça. Donc si vous pouvez m’aiguiller sur ce sujet je serai très reconnaissant :slight_smile:

curl_setopt($ch, CURLOPT_COOKIEJAR, «  »); => Je ne crée pas de fichier (cela prend un certain temps) et ainsi, je peux immédiatement intercepter les cookies. Et ça résout problème s’il y a quelques personnes qui se connectent en même temps.

1 « J'aime »

Ah,
merci.
À noter que le plugin http que j’évoque plus haut vérifie bien 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. Il serait également possible d’appeler une page maison du site SPIP avec un curl maison qui fournirait le login et le mdp dans l’auth Basic si vous les avez.

1 « J'aime »

Bonjour Jluc, peux tu développer ce que tu expose dans ton dernier post? j’utilise le plugin Spip Headless (basé sur le plugin http abstrait) et cette authentification pourrait être le chainon manquant pour gérer l’autentification. Merci d’avance

Que veux tu savoir au juste ?

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

De mémoire :

  • 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

Merci pour ta réponse rapide.
permets moi d’expliquer le cas:
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é. les données y sont récupérées à l’aide d’Axios.

le souci vient du fait que pour utiliser le plugin Accès Restreint et Spip Zone, l’utilisateur doit être authentifié.

Le plugin Spip Headless, par défaut, affiche tous les objets publics (sans authentification). il faudrait donc que j’associe les droits de l’application à l’authentification de Spip. C’est en cherchant une piste pour y arriver que je me suis intéressé à ce sujet.
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.
J’ai essayé d’activer le jeton que propose le plugin, mais cela me donne une erreur 403 dans Axios pour l’instant.

const api = axios.create({
  baseURL: "https://xxxx/",
  headers: {
    "x-auth-token": "62461743-7438-4299-883a-65f594be3e91",
    "Content-Type": "application/json"   
  },
  responseType: "json",
  withCredentials: true
});

Sinon j’ai essayé aussi Http Basic Auth comme tu l’as suggéré sans succès

var username = "username";
var password = "password";
const token = `${username}:${password}`;
const encodedToken = Buffer.from(token).toString("base64");

const api = axios.create({
  baseURL: "https://xxxx/",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Basic " + encodedToken,
  },
  responseType: "json",
  withCredentials: true,
});

Merci d’avance pour les éventuelles pistes.

L’auth, c’est pas très compliqué… une fois qu’on fait comme il faut. Alors peut être cette discussion à mes début d’auth basic te sera t elle utile : [Résolu] Authentification HTTP

Dans mon cas ce sont 2 codes PHP qui interagissent pour le serveur et le client avec le plugin http alors je ne connais pas les spécificités du plugin headless s’il y en a. Et je ne connais pas Axios et les fonctions js que tu appelles.

Note que ça m’intéresse car j’ai découvert que le framework js Svelte permet des sites interactifs très réactifs, et j’aimerais bien découvrir son usage. Y a-t-il un rapport avec ce que tu fais ?

Svelte est très bien, il fait partie des meilleurs frameworks frontend Javascript.
Pour ma part je préfère vuejs, notamment pour sa courbe d’apprentissage très courte et sa structure pas trop compliquée.
Si tu veux utiliser spip comme backend et Svelte comme frontend, Axios a de très simples fonctions pour interagir avec spip via le plugin headless et il s’intègre bien à Svelte.

Si tu as besoin d’aide pour intégrer spip à Svelte n’hésites surtout pas

Sinon je vais jeter un coup d’œil à ton à ton ancien sujet pour mieux comprendre l’auth de spip.