Tout verrouiller

Comment protéger par mot de passe des rubriques ou des articles

Ceci est une ARCHIVE, peut-être périmée. Vérifiez bien les compatibilités !

Comment sans bidouiller dans le noyau de Spip on peut à l’aide des mots clés des boucles et de php placer des articles et des rubriques en acces protégé.

Introduction : protéger son site avec SPIP

Restreindre l’accès à certaine partie de son site semble un besoin récurrent des webmasters de sites sous SPIP. Plusieurs solutions existent, la plus classique étant celle expliquée (un peu succintement) sur le site officiel qui permet de réserver certaines parties du site aux seuls membres authentifiés (rédacteurs ou visiteurs enregistrés). Ici nous allons détailler une autre méthode, à l’aide des mots clés, qui est loins d’être parfaite, mais qui suffira largement dans la plupart des cas simples.

Qu’est-ce que cette contrib permet de faire ?

Permettre aux administrateurs du site de placer certains articles
ou certaines rubriques en accès par mot de passe.

On pourra avec ceci créer autant de mots de passe que l’on voudra.
Protéger la rubrique les saucisses avec le mot de passe sauciflon sec
et la rubrique jambon avec le mot de passe jamblon sec.

Je protégerai pas mon compte en banque avec mais ça risque d’être suffisant pour la plupart
des besoins.
Plus precisement, allez voir un peu plus loin dans l’article : Les limitations du systeme.

C’est surtout très facile a mettre en place.

Installation

moins de 5 minutes
-  Décompresser acces.zip et installer controle_acces_rubrique.html controle_acces_rubrique.php3
controle_acces_article.html controle_acces_article.php3 FA2.php3 et enregistre_session2.php3 à
la racine de votre site.

-  Créer un groupe de mot clé que vous appelerez « acces multiple »,vous cocherez les bonnes cases
pour que ce groupe ne soit accessible qu’aux administrateurs et puissent être associés aux articles et
aux rubriques.

-  Notez soigneusement le numéro id_groupe de ce groupe de mots clés, vous en avez impérativement
besoin !!! nous le nommerons désormais <votre id_groupe>
(attention ne confondez pas id_mot avec id_groupe)

-  dans ce groupe créer 2 mots « sauciflon sec » et « jamblon sec »

-  puis au TOUT DÉBUT (cad à la premiere ligne au premier caractère) de article.html
placer ce code.

<INCLURE(controle_acces_article.php3){id_groupe=<votre id_groupe>}{id_article}>

-  puis au TOUT DÉBUT (cad à la premiere ligne au premier caractere) de rubrique.html
placer ce code.

<INCLURE(controle_acces_rubrique.php3){id_groupe=<votre id_groupe>}{id_rubrique}>
  1. Choisissez un article ou une rubrique de votre choix , associez le mot « sauciflon sec » et cliquez
    sur aller voir en ligne. Rentrer « sauciflon sec » dans le Formulaire d’Accès (FA) et si tous se passe bien votre article
    ou votre rubrique apparaît.

Et voila c’est fini

Et pour les courageux voici

Les Explications

Nous présenterons ce travail en deux temps

-  Temps 1 : on implémentera un accès restreint pour les articles seulement
car c’est plus facile.
-  Temps 2 : En se servant de ce qui a été fait au temps 1
on implémentera l’accès restreint pour les rubriques, ce qui exige une démarche
d’acquisition des informations qui peuvent être éventuellement présentes
dans les rubriques parentes.

Temps 1

-  controle_acces_article.html

<BOUCLE_acces(MOTS){id_groupe}{id_article}{0,1}>
<?php $acces='#TITRE'; ?>
</BOUCLE_acces>
<?php
//si la variable $acces a ete cree alors on lance le script
//cad si un acces restreint est bien associé a l'article
    session_start();
    //echo "variable de session".$_SESSION['$acces'];
if (isset($acces)){
    //recuperation du nom de script avec les arguments de requettes
    $origine=$HTTP_SERVER_VARS['SCRIPT_NAME']."?".$HTTP_SERVER_VARS['QUERY_STRING'];
    //on demarre une session

    //et on verifie si la variable $acces
    //est bien presente dans le contexte de session
    //et si le temps qu'elle contient n'est pas trop vieux
    //cad depasse de 5 minutes
    if ( isset($_SESSION['$acces']) and ( (date("U")-$_SESSION['$acces']) < 10 )and ($_SESSION['demande_enregistrement']==$acces) ){

        //on raffraichit la valeur
        //et on l'enregistre dans le contexte de session
        $_SESSION['$acces']=date("U");
    }else{
        //l'utilisateur n'a pas ete enregistre ou sa date d'enregistrement est trop vielle
        //on efface $$acces du contexte de session
        unset($_SESSION['$acces']);
        // a la place on enregistre une variable demande_enregistrement dont la
        //valeur depend de acces
        $_SESSION['demande_enregistrement']=$acces;
        //on dirige l'utilisateur vers le FA en sauvant son article demande
        header("location: FA2.php3?origine=$origine");
    }
}

Attention il ne doit y avoir aucun espace entre le début du fichier et ce script
car on fait appel à la fonction header qui ne peut être appelé que si aucune information
n’a été expédié au navigateur avant son invocation.

-  Le FA ou Formulaire d’Accès

Il est sans mystère voici son code FA2.php3
Il va collecter un mot de passe qui sera envoyé à un script de contrôle et d’enregistrement

<?php
//correspond a l'article demandé
$origine=$HTTP_GET_VARS['origine'];
//Si le mot de passe est erronée on renvoie ce message
$erreur=$HTTP_GET_VARS['erreur'];
?>
<html>
<body onload="mdp.getFocus()">
<?php if(isset($erreur)) echo $erreur; ?>

<div style='position:absolute;top:30%;left:30%'>
<form action="enregistre_session2.php3?origine=<?php echo $origine; ?>" method="POST" >
<p>l'acces a cette rubrique (ou article) est protégé par un mot de passe</p>
<input type=password name="mdp">
<input type=submit value="valider">
</form><br>
<a href="sommaire.php3">Retour au site publique</a>
</div>
</body>

-  Puis le script d’enregistrement

enregistre_session.php3

<?php
$origine=$HTTP_GET_VARS['origine'];
$mdp=$HTTP_POST_VARS['mdp'];
session_start();
//on recupere la demande d'enregistrement à $acces
$acces=$_SESSION['demande_enregistrement'];
//debug echo "mdp: $mdp acces : $acces";
if ($mdp==$acces){
    $_SESSION['$acces']=date("U");
    //debug echo "valeur de _SESSION  est ".$_SESSION['$acces'];
    header("location: $origine");
}else{
    $erreur="votre mot de passe est erroné votre administrateur l'a peut-etre change";
    header("location: FA2.php3?erreur=$erreur&origine=$origine");
}
?>

Ce script récupère la demande d’enregistrement qui est une variable de session qui contient le titre
du mot clé. Puis il compare cette valeur avec le mot de passe entré dans FA2.php3 si celui-ci est
bon il crée la variable de session $acces qui contient la date à laquelle l’utilisateur s’est enregistré

Et voila l’affaire est dans le sac si vous m’avez lu jusque
la je félicite votre patience :)

Temps 2 : généralisations aux rubriques

La généralisations aux rubriques est un peu plus subtile car il faut
pouvoir gérer les problèmes d’acquisition (qui sont très bien gérées dans Zope par ailleurs)

En effet si une rubrique se trouve être la sous rubrique d’une rubrique en accès par mot de passe
elle doit pouvoir hériter de ses propriétés. Tous les articles d’une telle rubrique aussi.

Ce qui va se résoudre à coup de boucle hiérarchie.

controle_acces_rubrique.html

<?php
    //vérifie si une rubrique parente
    //est en acces par mot de passe
?>
<BOUCLE_contexte_rubrique(RUBRIQUES){id_rubrique}>
<BOUCLE_hierarchie_acces(HIERARCHIE){id_rubrique}>
<BOUCLE_parent_acces(MOTS){id_rubrique}{id_groupe}>
<?php $acces='#TITRE'; ?>
</BOUCLE_parent_acces>
</BOUCLE_hierarchie_acces>
</BOUCLE_contexte_rubrique>
<?php
    //vérifie si la rubrique elle meme
    //est en acces par mot de passe
?>
<BOUCLE_acces_rubrique_simple(MOTS){id_rubrique}{id_groupe}>
<?php $acces='#TITRE'; ?>
</BOUCLE_acces_rubrique_simple>
<?php
//si la variable $acces a ete cree alors on lance le script
//cad si un acces restreint est bien associé a la rubrique
    session_start();
    //echo "variable de session".$_SESSION['$acces'];
if (isset($acces)){
    //recuperation du nom de script avec les arguments de requettes
    $origine=$HTTP_SERVER_VARS['SCRIPT_NAME']."?".$HTTP_SERVER_VARS['QUERY_STRING'];
    //on demarre une session

    //et on verifie si la variable $acces
    //est bien presente dans le contexte de session
    //et si le temps qu'elle contient n'est pas trop vieux
    //cad depasse de 5 minutes
    if ( isset($_SESSION['$acces']) and ( (date("U")-$_SESSION['$acces']) < 10 ) and ($_SESSION['demande_enregistrement']==$acces)){

        //on raffraichit la valeur
        //et on l'enregistre dans le contexte de session
        $_SESSION['$acces']=date("U");
    }else{
        //l'utilisateur n'a pas ete enregistre ou sa date d'enregistrement est trop vielle
        //on efface $$acces du contexte de session
        unset($_SESSION['$acces']);
        // a la place on enregistre une variable demande_enregistrement dont la
        //valeur depend de acces
        $_SESSION['demande_enregistrement']=$acces;
        //on dirige l'utilisateur vers le FA en sauvant son article demande
        header("location: FA2.php3?origine=$origine");
    }
}

et on fait pareil avec controle_acces_article.html

<?
    //verifie si la rubrique ou rubrique parente contenant
    //l'article est en acces par mot de passe
?>
<BOUCLE_contexte_article(ARTICLES){id_article}>
<BOUCLE_contexte_rubrique(RUBRIQUES){id_rubrique}>
<BOUCLE_hierarchie_acces(HIERARCHIE){id_rubrique}>
<BOUCLE_parent_acces(MOTS){id_rubrique}{id_groupe}>
<?php $acces='#TITRE'; ?>
</BOUCLE_parent_acces>
</BOUCLE_hierarchie_acces>
</BOUCLE_contexte_rubrique>
</BOUCLE_contexte_article>
<?
    //verifie si la rubrique ou rubrique parente contenant
    //l'article est en acces par mot de passe
?>
<BOUCLE_acces_article_simple(MOTS){id_groupe}{id_article}{0,1}>
<?php $acces='#TITRE'; ?>
</BOUCLE_acces_article_simple>
<?php
//si la variable $acces a ete cree alors on lance le script
//cad si un acces restreint est bien associé a l'article
    session_start();
    //echo "variable de session".$_SESSION['$acces'];
if (isset($acces)){
    //recuperation du nom de script avec les arguments de requettes
    $origine=$HTTP_SERVER_VARS['SCRIPT_NAME']."?".$HTTP_SERVER_VARS['QUERY_STRING'];
    //on demarre une session

    //et on verifie si la variable $acces
    //est bien presente dans le contexte de session
    //et si le temps qu'elle contient n'est pas trop vieux
    //cad depasse de 5 minutes
    if ( isset($_SESSION['$acces']) and ( (date("U")-$_SESSION['$acces']) < 10 ) and ($_SESSION['demande_enregistrement']==$acces)){

        //on raffraichit la valeur
        //et on l'enregistre dans le contexte de session
        $_SESSION['$acces']=date("U");
    }else{
        //l'utilisateur n'a pas ete enregistre ou sa date d'enregistrement est trop vielle
        //on efface $$acces du contexte de session
        unset($_SESSION['$acces']);
        // a la place on enregistre une variable demande_enregistrement dont la
        //valeur depend de acces
        $_SESSION['demande_enregistrement']=$acces;
        //on dirige l'utilisateur vers le FA en sauvant son article demande
        header("location: FA2.php3?origine=$origine");
    }
}

Limitations du système

-  Un accès par http://mon_site.org/mot.php3?id_mot=XX permet de deviner le mot de passe en incrémentant simplement XX à partir de 1, sur un site contenant peu de mots clés, facile de le trouver, pour remedier à cela il faut supprimer le couple de fichiers mot.php3/mot.html, et y repenser en cas de mise à jour de SPIP.
Ou alors dans le squelette mots.html modifier la Boucle MOTS : <BOUCLE_de_mots(MOTS){les criteres deja present}{id_groupe!=<groupe  des codes secret>}>

-  Il faut s’assurer que les divers squelettes alternatifs ou récapitulatifs (backend, resume, nouveautes, /oo, imprimer, plan, recherche, etc...) n’afficheront pas d’articles qui exigent un mot de passe. C’est très frustrant pour un visiteur de se faire présenter une liste d’articles dont on lui refuse l’accès. Pour cela il faudra exclure les articles correspondants :
Par exemple a l’aide d’une première boucle et du critère doublons :

<BOUCLE_articlesproteges(ARTICLES){les criteres deja present}{id_groupe!=<groupe  des codes secret>}{doublons}></BOUCLE_articlesproteges>
<BOUCLE_principale(ARTICLES){mes criteres}{doublons}>...</BOUCLE_principale>
 

-  Il faut penser à ajouter quelques directives dans son fichier robots.txt pour que Google et compagnie n’indexent pas des articles accessibles par mot de passe.

Ouf, quel travail pour protéger quelques articles !

Discussion

59 discussions

  • 7

    courcy, le 29 février 2004 :

    Bonjour à tous, en tant qu’auteur de cet article je tiens à vous dire que les choses ont progressé depuis ça et que tres bientot nous allons vous présentez une méthode de mis en acces reservé d’article ou de rubrique plus sur plus puissante et surtout beaucoup plus simple....

    Est-il possible de suivre - sur un forum publique par exemple - l’évolution de la recherche de solutions sur ce thème ?

    Et sinon, est-il possible d’avoir une estimation de la date à laquelle cette nouvelle méthode plus puissante et plus simple sera disponible ?

    Et encore Merci pour le travail déjà offert !

    • dans deux ou trois semaines environ

    • le Jamais Content

      2 ou 3 semaines... pffff... bon d’accord alors, mais pas plus, hein ! ;-)

      Sinon pour faire patienter, ça reposerait autour de quelles nouvelles boucles ?

    • je cherche toujours où suivre les discussion autour de ce sujet.
      j’ai cherché sur les listes de diffusions de spip, spip-dev, sur le forum de spip-contrib... sans succès :(

      par ailleurs les 3 semaines sont passées... ;)

      merci pour toute info !

    • Pour l’insant c’est avec des mots clés comme sur le bloog, il est en cours de traduire tout ca avec des extra, sur le meme principe.

    • c’est un peu comme les passagers d’un avion ... ;)

      ils aiment bien quand le pilote peut leur donner une estimée de l’heure de décollage ...

      -  ou encore mieux : pouvoir suivre l’évolution des débats autour de ce qui va permettre ce fameux décollage !

      -  et même, parfois, y’a des passagers qui ont des bonnes idées ;)

      Blague à part, y a-til une liste de diffusion ou un forum, sur lequel ont peut suivre les discussions sur ce sujet, histoire d’être moins passif dans cette histoire ?

      Et si c’est pas possible - pour x raison - pouvez-vous les donner ?

      amicalement,
      dieudo

    • Blague à part, y a-til une liste de diffusion ou un forum, sur lequel ont peut suivre les discussions sur ce sujet

      Je pense que c’est ici qu’on en parle le plus, grace a toi, n’hésite pas à signaler des idées !

      Mais en fait le plus gros du dossier a deja été plaidé, il faut juste remplacer les mots clés par des extras dans les fonctions existantes, ne manque que le temps pour le faire.

    • Salut,
      j’ai proposé ca : http://www.uzine.net/spip_contrib/ecrire/articles.php3?id_article=453, mais je n’ai pas beaucoup de retours sur le sujet.

      Ca ne correspond pas forcement à ton besoin (c’est surtout une protection des articles) mais ca peut etre adapté facilement.

      Pour l’instant, le plus gros probleme pour la protection des articles, c’est l’accès aux documents joints ...

      Si vous avez des idées, parcque la, je seche un peu (j’ai voulu faire un accès via un download.php, mais il faut aller faire des modifs un peu partout).

      Sinon, quelqu’un a des competences en SSL ? sur la config des .htaccess ?

    Répondre à ce message

  • Bonjour je n’ai jamais réaliser de site internet que ce soit sur SPIP ou non.
    Cependant j’ai une idée très précise de la structure que j’aimerai faire pour mon site. Je veut avoir une page public ou tout le monde peut avoir accès. Ensuite une page Membre accessible qu’aux membres avec un mot de pass(de la page public). Et pour finir un espace privé ou juste les auteurs et les administrateurs auront accès.

    Ma question est la suivante :
    Est ce que ta contribe peut me servire pour limiter l’accès de ma page privé aux membres ? cad plusieur groupes de membres n’ont accès que à un espace qui leur est reservé

    Merci d’avance de bien vouloir me repondre sur ce forum ou m’envoyer un mail/

    Répondre à ce message

  • l.cacheux

    Ne serait-il pas possible de présenter cela autrement. Je m’explique : au lieu de mettre un id_groupe fixe, on pourrait mettre un type_mot , non ??

    Sinon bravo pour cette contrib.

    l.cacheux

    Répondre à ce message

  • 3

    Bonjour à tous, en tant qu’auteur de cet article je tiens à vous dire que les choses ont progressé depuis ça et que tres bientot nous allons vous présentez une méthode de mis en acces reservé d’article ou de rubrique plus sur plus puissante et surtout beaucoup plus simple....

    C’est pourquoi je vous invite à ne pas trop vous « battre la dessus ». Car ce sera tres bientot completement caduque.

    @+

    • Ah ben en tant qu’utilisateur -ravi- de tout ce système infernal, je tiens à te remercier vivement pour ce boulot (toi et les autres qui ont bossé dessus bien sûr !)

      Je prends donc note que le site de mon école sera prêt à temps et super sécurisé pour une info en temps réel de la classe transplantée, début mai...

      Cool !

      Plaisanterie mise à part, merci encore

    • Bonjour,

      Merci beaucoup pour cette future version.

      Bravo à toute l’équipe.

    • Je confirme que cette fonction est très attendue !

      Merci d’avance ;)

    Répondre à ce message

  • Euh... pour ceux qui auraient eu la joie de découvrir cela à l’ouverture d’un article ou d’une rubrique protégé :

    Fatal error : open(O_RDWR) failed for session file. The error is No such file or directory (2).

    et qui n’auraient pas lu l’aide en ligne proposée dans ce cas (si si, j’en connais un, sur free...)

    Il vous faut pour que tout fonctionne que la gestion des sessions soit activée sur votre serveur... et donc placer vous même si ça n’a pas été fait tout seul un répertoire « sessions » à la racine de votre site.

    Moi je dis ça... je ne dis rien :-)

    Répondre à ce message

  • Bonjour,

    Avez-vous déjà eu ce message sous IE ?

    « mdp est indefini »

    J’ai dû l’enlever mais je ne comprends pas pourquoi ça fait ça ??

    @+

    Txia
    @Lyfoung

    Répondre à ce message

  • 1

    Bonjour !
    Quelle ne fut pas ma joie de découvrir cette contrib !!!
    ....mais j’ai exactement le même problème que « Pierre-Edouard, le 9 octobre 2003 » (un peu plus bas dans cette page).....et je ne pige vraiment pas pourquoi (pourtant, moi, mon fichier s’appelle bien « rubrique.html » et effectivement, ce fichier contient une mise en page perso (un squelette quoi). Est-ce cela qui produit le message d’erreur ??

    Merci de me faire parvenir vos lumières jusqu à moi (je ne suis pas bien loin)

    Et merci encore pour cette contrib !!

    Greg

    • Idem.
      Je pense que cela vient d’Online (mon hébergeur) qui doit avoir une ancienne version de php...

    Répondre à ce message

  • casimopon

    formidable contrib,
    merci.

    cependant, dans mes squelettes autres,sommaire, oo, ..

    je mets le critère :

    BOUCLE_aa(ARTICLES)id_groupe !=1
    j’ai rien du tout (aucun article)
    en revanche si je mets id_groupe=1

    il m’affiche bien les articles protégés et uniquement eux (c’est le bon id_groupe)

    à l’envers il marche bien !

    apparament il comprends pas le !=
    j’en suis à mon quatrième tube de calmant

    dans la meme boucle j’ai un
    id_rubrique !=2 qui marche

     :(

    merci

    Répondre à ce message

  • Bonjour,

    Comme débutant, j’ai suivi l’installation rapide et tout fonctionne correctement sauf l’apparition du message

    Notice : Undefined index : erreur in c :\program files\easyphp1-7\www\cfpcharleroi\fa2.php3 on line 5

    En adaptant cette ligne en :

    if(isset($erreur)) $erreur=$HTTP_GET_VARS[’erreur’] ;

    je n’ai plus de problème.

    Serait-ce spécifique aux paramètres d’environnement (EasyPHP) ?

    Répondre à ce message

  • Bonjour à tous. Nouveau mais très content de cet outil, je me sui aperçu que beaucoup de liens ( de type http://www.uzine.net/spip_contrib/article.php3?id_article=201 ) de ce site pointe vers uzine.net alors qu’il suffirait de ne changer que le terme uzine contre « spip » et l’on arrive directement vers le bon lien (les articles n’ayant pas bougé)

    Un admin pourrait-il mettre à jour tous ces liens ???

    merci pour tout

    redb

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom