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}>
- 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 !
Discussions par date d’activité
59 discussions
salut à tous j’ai problème étrange avec spip 1.7.2
est bien à la première ligne de mon squelette article-19.html
le groupe mot clé bien relié à l’article et aux rubriques
lorsque que je recalcul mon squelette
page blanche systématiquement il me semble que c du à la balise inclure
modèle de mon entête ( j’ai enlevé exprès les tags
INCLURE(controle_acces_article.php3)id_groupe=2id_article
!DOCTYPE HTML PUBLIC « -//W3C//DTD HTML 4.01 Transitional//EN » "http://www.w3.org/TR/html4/loose.dtd"
BOUCLE_article_principal(ARTICLES) id_article
html lang=« #LANG »
...................
Je comprend pas si une personne ayant déja eu le même pb pouvait se manifester ca serait super merci à toute la communauté
Répondre à ce message
J’obtiens l’erreur :
’Erreur(s) dans le squelette o erreur d’exécution de la page, Kouymol error : kouymol error, unexpected Ptite_Bite in /home/.sites/47/site99/web/inc-public.php3(56) : eval()’d code on line 242’
C’est grâve docteur ?
Répondre à ce message
Eh bien voila, je propose aux lecteurs de cet article de passer à la version hierachisée des acces restreint
qui est beaucoup plus sur que cette contrib et vous permet de hierarchisée les droits de vos visiteurs.
MERCI !
;D)
Comment peut-on accèder à cette nouvelle version qui semble très intéressante ?
DJ
bonjour,
oui, comment acceder a cette nouvelle mouture ?
merci
Pas mal et efficace effectivement, cela va me rendre bien service.
Un bug ??? lorsque je reviens sur la page de gestion des invités, ce n’est pas leur login qui apparait, et qq difficultés pour supprimer un visiteur, je dois passer via phpmyadmin pour en etre sur. mauvaise manip de ma part ?
Comment faire pour tester cela « à fond » en local ? si un invité demande son inscription ?
Bravao encore
amicalement
Impossible de telecharger la contrib, le lien est brisé !
C’est normal ?
manu
Pareil, le lien ne marche pas !!!
Le lien pointe vers l’espace privé... Impossible de télécharger la version hiérarchisée (pourtant très alléchante !!).
Il semble que Eric du 23 Avril 2004 y soit pourtant arrivé.
Alexis
Bonjour,
comment accèder aux scripts (zone privée).
Merci pour ton travail
RS
Dans son empressement, je pense que l’auteur a copier-coller le lien depuis son backoffice. Le lien vers l’article est : http://www.spip-contrib.net/article...
Par contre, attention, il semblerait que cette contrib ne soit pas applicable à la version 1.8 :-((
Répondre à ce message
Bonjour,
Après la mise à jour en SPIP 1.8, il semblerait que votre mode de protection ne marche plus. Avez-vous constaté la même chose ?
Les symptômes sont :
- pour les articles : authentification ignorée
- pour les rubriques :
* Erreur(s) dans le squelette
o erreur d’exécution de la page,
Parse error : parse error, unexpected T_STRING in /home/.sites/47/site99/web/inc-public.php3(56) : eval()’d code on line 242
Je vous tiens au courant si je trouve la solution...
Nicolas
Merci d’ignorer le précédent message, l’erreur provenait d’ailleurs.
Par contre, j’obtiens maintenant un :
Et pourtant, j’ai suivi les instructions à la lettre :
- je n’ai laissé aucun espace avant d’insérer la ligne en haut de mes fichiers article.html et rubrique.html
- j’ai créé un dossier « sessions » à la racine de mon site (je suis hébergé chez Amen)
Quelqu’un aurait-il une idée ??
Nicolas
Répondre à ce message
C’est nickel et ça marche super ...
Seul bémol, le mot de passe à accessible via l’interface de rédaction en consultant les mots clef => lorsque l’inscription à la partie rédactionnelle est activé de façon automatique, un simple rédacteur peut donc y accéder facilement !! :-(
La seul solution, désactiver l’inscription automatique de nouveaux rédacteurs . Dommage.
Sinon, très bon moyen pour filtrer un minimum ;-)
Répondre à ce message
Bonjour,
merci et félicitation pour pour cette contrib qui m’aide beaucoup, ca marche super chez moi (hébergeur free).
Dom75
Répondre à ce message
Salut tout le monde !
Bon j’ai tout lu ! et malgres ca !! probleme ! J’ai un bug et j’arrive pas a le résoudre ! voici le bug ke j’ai :
Warning : session_start() : open(/var/www/free.fr/6/f/cisv.alsace/sessions/sess_af255702dd30816f46b46c04676d9208, O_RDWR) failed : No such file or directory (2) in /var/www/free.fr/6/f/cisv.alsace/enregistre_session2.php3 on line 4
Warning : session_start() : Cannot send session cache limiter - headers already sent (output started at /var/www/free.fr/6/f/cisv.alsace/enregistre_session2.php3:4) in /var/www/free.fr/6/f/cisv.alsace/enregistre_session2.php3 on line 4
Warning : Cannot modify header information - headers already sent by (output started at /var/www/free.fr/6/f/cisv.alsace/enregistre_session2.php3:4) in /var/www/free.fr/6/f/cisv.alsace/enregistre_session2.php3 on line 14
Warning : Unknown() : open(/var/www/free.fr/6/f/cisv.alsace/sessions/sess_af255702dd30816f46b46c04676d9208, O_RDWR) failed : No such file or directory (2) in Unknown on line 0
Warning : Unknown() : Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/var/www/free.fr/6/f/cisv.alsace/sessions) in Unknown on line 0
enfin voila ! si l’auteur de cette article pouvais me donner un petit coucou de main ca serait super !!!
Merci beaucoup d’avance !!!
même chose pour moi...
je suis sous la derniere version de spip 1.7.2
Quelqu’un peut-il confirmer que cela marche avec cette version ?
comme quoi on lit pas les faq en entier !!
Il faut creer à la main un repertoire « sessions » sur le site.
Voila.
J’ai beau avoir suivi les consignes à la lettre eh bien il n’y a aucune restriction aux accès, « tout le monde » peut voir le contenu de la rubrique...
J’ai eu le même problème suite à la mise à jour du serveur de mon hébergeur (tout fonctionnait correctement avant), et le problème est aussi présent sur un autre serveur. Je pense avoir testé tout ce qui est proposé sur le forum, mais j’ai toujours Warning : session_start() : Cannot send session cookie - headers already sent by (output started at /home/polo.net/site/spip/CACHE/2/con-2-27.33940e.NEW:5) in /home/polo.net/site/spip/CACHE/2/con-2-27.33940e.NEW on line 8
Merci pour tout début de réponse, cette fonction est très pratique...
Répondre à ce message
Tout d’abord, un grand merci au créateur de cette contib !
Je l’ai installer sur mon site et ca fonctionne nickel.
Seulement voilà, j’aurais aimé rediriger mes visiteurs sur une page spécifique à chacun, lors de leur identification. L’idée étant de leur permettre un accés à un espace personel sur mon site public lors de leur identification.
Pour l’instant j’utilise la boucle du type (#login_public|rubrique-X.html) pour spécifier la page appelée lors du login. Mais je suis obligé de poser sur ma page html une boucle spécifique pour chaque client (x, y, z...).Ca fait lourd
Comment faire pour orienter automatiquement mes client sur leur espace privé lors de l’identification avec une seul boucle login_publique ???
J’ai trouvé le script sur phpscripts.fr (voir le lien), mais je ne sais pas comment l’appliquer à la contrib de Concil.
Merci de votre aide.
Répondre à ce message
Bonjour, avec ce système, serait-il possible de rendre les articles accessibles avec le mot de passe seulement quelques jours, 30 environ, et qu’ensuite, il deviennent accessibles à tous.
Si oui, comment, car en plus, chaque squelette devrait comprendre quand il peut autoriser l’accès et quand il doit le limmiter.. :-(( pas simple.
Dommage qu’on ne puisse pas être prévenu des réponses...
Merci si qq’un-e me trouver la solution.
Répondre à ce message
Salut à tous,
je suis un petit nouveau sur Spip, et ma première phrase sera donc un grand merci pour le travail accompli et mis à notre disposition !
Concernant la protection par mot de passe d’articles et rubriques, j’aimerai savoir vers quelle contrib il faut se tourner à l’heure actuelle. La lecture des messages de ce forum m’a fait comprendre que la contrib de départ avait connu des évolutions, mais je ne trouve aucun lien renvoyant vers un nouveau zip ou une autre contrib. Quelqu’un peut-il m’éclairer ?
Merci d’avance !
il me semble que la réponse est dans le message de Courcy du 06 avril !
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 :
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.
Suivre les commentaires : |