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
Ca fonctionne nickel, sauf que j’ai chaque fois, tout en haut de la page afffichée, un « ?> » (sans les guillemets) qui traîne.
J’ai beau tout retourner, je ne trouve pas.
Une idée ?
Répondre à ce message
Dans les pack zippés, il y a un chemin d’accés (path) or j’ai bien lu dans cette contrib que les fichiers doivent être dézippés à la racine du site (www). En dézippant sans le chemin, effectivement, ça fonctionne mieux... avec les liens direct (/rubrique.php3 ?id_article=20).
Ceci dit pour aider ceux qui ont eu ce genre de problème.
A part ça, j’utilise toujours les squelettes de base qui affichent royalement mes fichiers cachés.
Je crois que la solution est plus haut dans la contrib. J’y retourne immédiatement...
Be aware !
Ceci dit en local avec easyphp, suis pas encore au site distant.
Répondre à ce message
Bonjour !
J’ai bien tout fait comme c’est indiqué. Mais invariablement, j’ai droit à cette phrase, que le mot de passe soit bon ou pas :
Je précise que je teste ça en local, sur mon serveur Apache sous Windows 2000 et SPIP 1.5.2. Que me suggérez-vous ?
Désolé mais cette contrib est prévu pour la 1.6 car elle utilise les groupes de mot clé.
A tout hasard, j’ai mis ça en ligne sur le serveur du site. Et là, miracle, ça marche !
Mais j’aimerais bien qu’on m’explique pourquoi ça ne marche pas sur mon serveur perso. Y a-t-il un paramètre à appliquer ? Une mise à jour à faire ?
Ca semble marcher aussi sur la 1.5.2, version dans laquelle on a les groupes de mots-clé.
Répondre à ce message
Pour trouver le no du groupe essayer un squellette comme celui-ci
Bon courage
Répondre à ce message
Cette méthode marche super pour des articles auxquels on accède de manière classique mais comment faire lorsque l’on a créé des squelettes particuliers aux rubriques que l’on veut protéger. En effet, ils sont accessible si l’on inscrit leur adresse dans la barre de navigation.
Je me répond moi-même :
En fait il faut semble-t-il modifier $origine dans les différents fichiers du pack en lui affectant le nom du squelette (chez moi c’est rubrique-50.php3 par exemple) et procéder de même pour les autres squelettes.
Par contre comment faire pour protéger du coup les forums reliés à ma rubrique comme on ne peut pas il me semble leur affecter des mots clés. Est-il possible de tester juste si la session est toujours en cours et sinon orienter vers le FA50 ?
J’ai une méthode dérivée de celle ci qui utilise le formulaire d’identification spip.
Elle devrait te permettre de protéger n’importe quoi dans ton site.
@ +
BoOz
Répondre à ce message
Lorsqu’un rédacteur accède à l’dition du site, dans mots clés, il ne peut rien créer mais il a peut lire l’intégralité des codes (mots).
J’ai bien paramétré le groupe sous spip 1.6
il s’agit du fonctionnement normal de spip, on ne peut pas protéger des articles « contre » les rédacteurs.
Répondre à ce message
Il me semble que votre bidule pour protéger l’accès de rubriques ou d’articles est qd même vachement plus complexe que Xprotector (cf autre contrib « je ne sais plus où ? »). Mais peut être n’ai je pas vu certaines faiblesse liées à Xprotector ?
Mon bidule cher ami ne s’appuie pas sur la liste des mots de passe integré dans la base mais sur un mot de passe choisi comme mot-clé, les buts poursuivis ne sont pas ceux de X-protector. La simplicité d’installation est tres grande les explications sur son fonctionnement sont plus complexes il en va de meme pour X-protector... Peut-etre avez-vous confondu ces 2 problemes, peut etre n’avez-vous pas vraiment lu dans le détail, peut etre avez-vous survolé, qui sait ?......
Répondre à ce message
Super contrib, très facile d’utilisation !
Au fait, je ne vois pas la nécessité de supprimer le couple mot.php3 / mot.html.
Car cela ne permet pas de visualiser les mots-clés.
Quand je fais : http://mon_site.org/mot.php3?id_mot=n
Je ne vois qu’un bouton « modifier », avec l’id du mot-clé mais pas sa description.
Je ne probablement pas tout compris...
Merci d’avance pour votre réponse.
A+ Laurent
P.S. Je suis en SPIP 1.6
Et bien si en tapant dans ton brouteur mot.php3 ?id_article=x ou x varie de 1 au nombre de mots clés tu réalises rapidement que tu peux obtenir la liste de tous les mots clés utilisés pour le site : ceux pour les mots de passe et ceux pour d’autres utilisations un courageux h acker n’a plus qu’a tous les essayé.......
Il faut alors garder le couple mots.php3/.html et ajouter dans la boucle MOTS du squelette mots.html, le critère
{id_groupe!=2}
(si 2 est le numéro du groupe « acces multiple »).
C’est expliqué dans l’article (limitations).
Répondre à ce message
Le fichier FA2.php3 contient une faute, il faut remplacer « site publique » par « site public ».
Répondre à ce message
Ouais pas mal ! Mais ya un blem : les docs joints aux articles et/ou rubriques protégées sont toujours accessibles non ? Il suffit d’aller à l’adresse www.monsite.fr/spip/IMG/ ...
Bonjour,
si tu mets un fichier .htaccess qui contient l’instruction deny from all dans ton rerpertoire IMG, il ne sera plus accessible a personne non ? C’est ce qui me parait le plus simple.
Bonjour ;
en fait j’ai copié le fichier htaccess dans /IMG effectivement le repertoire IMG est devenu inaccessible a personnes mais j’ai un probleme c’est que les images liées aux articles proteges ne s’affichent pas et aussi les documents joints ne sont pas telechargable que puis je faire ?? et merci
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 : |