Bonsoir à tous !

J'ai regardé les derniers tutos (portfolio) et je souhaite donc faire mon petit site. Pour cela j'essaye de ne pas faire de c/c et de créer moi même les script en piochant à droite à gauche des idées.

Pour le coup j'essaye de faire une sécurisation des pages admin, via un champ rang de ma bdd.

Mon code fonctionne mais je le trouve pas du tout optimisé.

Voici le code

<?php 
$admin = 1; 
if (!empty($_SESSION)) {
    if (isset($_SESSION'rang'])) {
        if ($_SESSION'rang'] != $admin) {
                header('Location:../index.php');
                die();
        }else{
            echo 'Welcome';
        }
    }
}else{
    header('Location:../index.php');
    die();
}
?>

Dans ma BDD, j'ai pour le moment un user (moi :p) et comme rang par défaut 1(membre) mais comme je souhaite être admin, j'ai passer le champ à 0

A chaque page d’administration admin, je dois inclure la page. J'ai pensé faire une fonction, mais j'ai vraiment du mal à l'imaginer et encore plus la concevoir...

Avez vous une piste ou un début d'idée à me partager? Merci d'avance !

11 réponses


Gyuki
Réponse acceptée

Bonjour,

Tout d'abord, tu dis que les membres ont le champs rang a 1 et pourtant tu met une variable admin a 1, c'est ambigue.
Tu devrais plutot mettre la variable admin a 0 et faire le if avec un == plutot qu'un !=
Avec un != le jour ou tu rajoute un autre rang, (modérateur, VIP, etc...) et qu'ils auront un rang superieur a 1, il auront les droits admin puisque tu test la différence a 1 et donc 0 est vrai tels que 2, 3, etc sont vrai aussi.

Dans le code suivant, je test $_SESSION, si c'est vide alors je redirige vers index. En faisant sa, je n'ai plus besoins de else.
Si c'est faux et que $_SESSION n'est pas vide, alors le script continue et test l'existence de rang dans la variable. Si c'est vrai alors je test si dans la variable, c'est le rang admin (0) sinon je redirige.

<?php 
    $admin = 0; 
    if (empty($_SESSION)) {
        header('Location:../index.php');
        die();
    }
    if (array_key_exists('rang', $_SESSION)) {
        if ($_SESSION'rang'] == $admin) {
            echo 'Welcome';
        }else{
            header('Location:../index.php');
            die();
        }
    }
?>

Désolé pour les fautes mais le français et moi sa fait 4.

jeranders
Auteur
Réponse acceptée

Voilà, j'ai fait une petite fonction (je suis fier de moi !)

function autorisation($id){
    $id = $_SESSION'rang'];
    $admin = 0;
    if(isset($admin) && $admin == $id){
        return true;
    }
    header('Location:../index.php');
    die();
}

Donc les pages ou je souhaite autoriser l'admin je mets
autorisation($_SESSION'rang']);

Gyuki
Réponse acceptée

Si tu veux en version petite :

function autorisation(){
    if(array_key_exists('rang', $_SESSION))
        return $_SESSION'rang'] == 0 ? true : header('Location:../index.php');
    header('Location:../index.php');
    die();
}

Ici je test l'existance de rang dans $_SESSION, si c'est vrai alors je test si oui ou non $_SESSION'rang'] = 0, si c'est vrai, cela retourn true et sinon sa redirige
Si l'existance de rang dans $_SESSION est faux, il redirige avec le deuxieme header juste au dessus du die.
Pour information, a coté du return c'est du ternaire

$_SESSION'rang'] == 0 ? true : header('Location:../index.php');
//est exactement la même chose que
if($_SESSION'rang'] == 0)
    return true;
else
    return header('Location:../index.php');

Imaginons que tu veuille avertir que quelqu'un n'a pas les droits d'acces a ta page car il n'est pas admin, tu vas devoir modifier ton code pour mettre ce qui faut a l'interieur de la fonction.
Avec la fonction de Pewel
tu n'aurais qu'a mettre le code dans le else qui test l'autorisation. ( if(autorisation()) )

Pewel-OutOfNutella
Réponse acceptée

Gyuki a tout dit :D

Quelque chose qu'il faut savoir aussi pour essayer de faire le code le plus propre possible :
-une fonction/méthode/classe doit avoir une et une seule fonctionnalité.

Je vais commencer par la classe.
Imaginons que tu ait une classe "Voiture". Elle ne va pas gérer des "Scooter" ou encore moins des "Camions".
C'est pourquoi un nom comme "Véhicule" peut être ambigüe parce qu'on ne sait pas trop son comportement.

Idem pour les fonctions/méthodes. Il faut essayer de créer des fonctions courtes, qui ont une fonctionnalité.
Si tu dois avoir une fonction qui test une valeur et après faire un traitement suivant cette valeur, il vaut mieux passer par plusieurs méthodes.

Exemple :

$voitures = array("BMW", "Mercedes", "Peugeot", "Fiat");
function getProprietaire($voitures, $key) {
    if (array_key_exists($key , $voitures)) {
        //requête sql pour aller chercher autre chose liée à la voiture en base (le propriétaire par exemple)
        $result = mysql_query("SELECT .....");
        $row = mysql_fetch_row($result);

        if($row[0] == "Durand") {
           ...
        }
    }
    else {
        //résultat non trouvé, autre traitement...
    }
}

Tu vois, cette fonction elle :
-vérifie l'existance de la clé dans la tableau
-va taper dans la bdd pour aller prendre un résultat
-fait autre chose si le résultat n'est pas trouvé

Ca fait beaucoup trop de traitement pour une seule et même fonction.
C'est pourquoi c'est plus lisible et plus facilement maintenable de découper tout ça en plusieurs fonctions :
-une fonction getProprietaire qui va retourner le proprietaire
-une fonction searchKeyInArray qui va faire une recherche dans le tableau
-une fonction selectInDataBase qui va interroger la Bdd

Exemple :

$voitures = array("BMW", "Mercedes", "Peugeot", "Fiat");
function getProprietaire($voitures, $key) {
    if (searchKeyInArray($key , $voitures)) {
        $results = selectInDataBase($params);
    }
    else {
        //résultat non trouvé, autre traitement...
    }
}
function searchKeyInArray($key, $tab) {
    //on peut immaginer faire un traitement sur un tableau beaucoup plus complexe
    return array_key_exists($key , $voitures);
}
function selectInDataBase($params) {
    //requête sql pour aller chercher autre chose liée à la voiture en base (le propriétaire par exemple)
    $result = mysql_query("SELECT .....");
    $row = mysql_fetch_row($result);

    checkProprietaire($row[0]);
}
function checkProprietaire($name) {
    if($name == "Durand") {
        //do something
    }
    else {
        //do another thing
    }
}

Voilà, j'ai pris des exemples simples mais plus ton code est fourni, plus il sera maintenable avec ces petites astuces.

Oui, le $admin est à 1 suite à des essaies pour voir si la condition étais bonne. J'avais changé entre temps :)
Merci pour ta réponse.
Je vais essayer de faire une fonction session_admin() pour pouvoir juste mettre la fonction en début de page, c'est pas gagné ^^

Bonjour,

Il est totalement inutile de tester l'existence de $admin => isset($admin) puisque tu initialise cette variable juste avant, donc le isset retournera toujours vrai.
Ce que tu devrai tester c'est plutot la session a moins que tu le teste avant l'appel de cette fonction. Ce qui signifie qu'aucun isset n'est necessaire.

En relisant un petit coup, je ne comprend pas pourquoi tu force a mettre un paramètre a la fonction si a l'interieur de la fonction tu ecrase le parametre ?
Ex: Si je fait ceci

<?php
autorisation($_SESSION'rang']);
function autorisation($id){
    //ici $id = $_SESSION'rang'] Alors pourquoi la ligne d'en dessous ?
    //si j'appelle la fonction ainsi : autorisation(3);
    //a la ligne suivante mon 3 sera ecraser par $_SESSION'rang'] donc mon 3 est inutile.
    $id = $_SESSION'rang'];
    $admin = 0;
    if(isset($admin) && $admin == $id){
        return true;
    }
    header('Location:../index.php');
    die();
}
?>

Cordialement.

Merci pour ta réponse.
J'avais test la session en dehors de la fonction, mais pour plus de facilité je l'ai ajouté dedans.

Avec ton aide voici le résultat

<?php 
function autorisation(){
    $id = $_SESSION'rang'];
    $admin = 0;
    if (!empty($_SESSION)) {
        if(isset($admin) && $admin == $id){
            return true;
        }
        header('Location:../index.php');
        die();
    }else{
        header('Location:../index.php');
        die();
    }   
}
?>
<?php 
function autorisation(){
    if (!empty($_SESSION)) {
        if(0 == $_SESSION'rang']) {
            return true;
        }
    }
    return false;
}
//quand tu veux faire appel
if(autorisation()) {
    header('Location:../admin/index.php');
}
else {
    header('Location:../index.php');
}

?>

Bonjour,

Pewel a sortie la fonction la plus adequate a ce que tu voulais.

En cours d'info, mon prof nous a toujours dit, qu'une fonction doit toujours retourner quelque chose et dans ta fonction a toi (jeranders) lorsque c'etait faux, tu ne retournais aucune valeur puisque tu faisait une redirection.
Avec la Fonction de Pewel, sa retourne soit vrai soit faux, mais sa retourne quelque chose ;)

Après je voulais pas lui pondre la fonction complète pour qu'il essaye de trouver par lui même ;)

Merci encore pour vos réponses ! :)

Au départ j'avais imaginé une fonction que j'appellerais dans ma page admin ou autre page "restreint" pour vérifier rapidement le rang de l'utilisateur donc juste faire un autorisation(); en haut de ma page admin.

Voici ma page admin pour exemple

<?php
/**
** Page d'administration
**/
include '../pages/includes.php';
include '../pages/auth_admin.php';
autorisation();
?>
<?php
include '../pages/header_admin.php';
?>
<h2>Admin</h2>
<div class="dev_1 col-md-10 col-md-offset-1 p_t_b">
    Salutation <?php echo $_SESSION'pseudo']; ?>
</div>
<?php
include '../pages/footer.php';
?>

Avec le code de Pewel je dois en plus faire une condition en plus de ce que je comprend, ce qui est moins intéressent non? (je débute donc j'essaye de comprendre ne pas mal le prendre ^^)

Et bah ! Je suis gâté ! Merci pour vos astuces ! J'avoue que c'est pas évident, mais je commence à comprendre un poil mieux comment faire des fonctions. Encore merci vous :)