Tutorials
Bitwise rechten systeem
Bitwise rechten systeem om te bepalen wie welke rechten heeft d.m.v. PHP.
Pagina 1
Inleiding
Wat handig is (maar niet noodzakelijk) om deze tutorial beter te begrijpen, verwijs ik naar een tutorial van Mitch genaamd bitwise operators. Hierin wordt uitgelegd wat bitwise operators zijn, hoe het werkt en wat je ermee kunt doen.
In deze tutorial zal ik je uitleggen wat de grote voordelen zijn van een bitwise rechten systeem, met daarin de nadelen van een 'gewoon' rechten systeem. Je zult door tekst en uitleg met veel voorbeelden uitgelegd krijgen hoe je een dergelijk systeem kunt opzetten.
In deze tutorial zal ik je uitleggen wat de grote voordelen zijn van een bitwise rechten systeem, met daarin de nadelen van een 'gewoon' rechten systeem. Je zult door tekst en uitleg met veel voorbeelden uitgelegd krijgen hoe je een dergelijk systeem kunt opzetten.
Pagina 2
Een manier van een rechten systeem
We gaan uit van een website die meerdere pagina's heeft en je wilt gebruikers verschillende rechten toewijzen. Iedere pagina heeft ook weer zijn eigen functionaliteiten:
Hoe zou jij dit oplossen? Je kunt dit namelijk op verschillende manieren doen. Hier een voorbeeld zoals het zou werken, maar niet optimaal is.
Om gebruikers te koppelen aan functionaliteiten maken we een tabel aan die functioneert tussen gebruiker en functionaliteiten met de kolommen:
De `tid` (to ID) verwijst naar de gebruiker en de rest spreekt voor zich.
Stel Klaas mag:
Dan zou een rij in deze kolom er als volgt uit zien:
Stel dat Klaas nu op 'wijzigen' klikt. Dan zou dat er in PHP zo uit moeten zien:
<?php
// connect to database
include('includes/database.inc.php');
// retrieve the rights
$rights_sql = "SELECT * FROM user_rights WHERE tid = " . mysql_real_escape_string($_SESSION['user_id']);
if (!$rights_res = mysql_query($rights_sql))
trigger_error('Fout in query: ' . mysql_error());
else
{
if (mysql_num_rows($rights_res) >= 1)
$rights = mysql_fetch_assoc();
}
// the different pages
if ($_GET['show'] == 'nieuws')
{
// add
if ($_GET['page'] == 'add' && $rights['news_add'] == 1)
echo 'Add news';
elseif ($_GET['page'] == 'edit' && $rights['news_edit'] == 1)
echo 'Edit news';
elseif ($_GET['page'] == 'delete' && $rights['news_delete'] == 1)
echo 'Delete news';
elseif ($_GET['page'] == 'approve' && $rights['news_approve'] == 1)
echo 'Approve news';
else
echo 'Show overview news items';
}
elseif ($_GET['show'] == 'games')
{
if ($_GET['page'] == 'add' && $rights['games_add'] == 1)
echo 'Add a game';
elseif ($_GET['page'] == 'edit' && $rights['games_edit'] == 1)
echo 'Edit a game';
elseif ($_GET['page'] == 'delete' && $rights['games_delete'] == 1)
echo 'Delete';
elseif ($_GET['page'] == 'approve' && $rights['games_approve'] == 1)
echo 'Approve a game';
else
echo 'Show overview with games';
}?>
Dit is een erg simpele manier om het te doen. Eéntje die ik ook vaak tegen kom en werkt, maar niet optimaal is. Stel nu dat een gebruiker die games mag verwijderen, ze ook automatisch mag toevoegen, wijzigen en goed mag keuren? Dan krijg je in PHP iets als:
<?php
if ($_GET['show'] == 'games')
{
if ($_GET['page'] == 'add' && ($rights['games_add'] == 1 || $rights['games_delete'] == 1))
echo 'Add a game';
elseif ($_GET['page'] == 'edit' && ($rights['games_edit'] == 1 || $rights['games_delete'] == 1))
echo 'Edit a game';
// etc
?>
Stel nu dat gebruikers die mogen wijzigen, ook mogen toevoegen, dan kun je erg lange if statements krijgen. Dit is niet het geval als je de bitwise methode gebruikt. Zie de volgende pagina voor uitleg.
Nieuws
- Toevoegen
- Wijzigen
- Verwijderen
- Goedkeuren
Games
- Toevoegen
- Wijzigen
- Verwijderen
- GoedkeurenHoe zou jij dit oplossen? Je kunt dit namelijk op verschillende manieren doen. Hier een voorbeeld zoals het zou werken, maar niet optimaal is.
Om gebruikers te koppelen aan functionaliteiten maken we een tabel aan die functioneert tussen gebruiker en functionaliteiten met de kolommen:
CREATE TABLE `user_rights` (
`tid` INT( 11 ) NOT NULL ,
`news_add` ENUM( '0', '1' ) NOT NULL ,
`news_edit` ENUM( '0', '1' ) NOT NULL ,
`news_delete` ENUM( '0', '1' ) NOT NULL ,
`news_approve` ENUM( '0', '1' ) NOT NULL ,
`games_add` ENUM( '0', '1' ) NOT NULL ,
`games_edit` ENUM( '0', '1' ) NOT NULL ,
`games_delete` ENUM( '0', '1' ) NOT NULL ,
`games_approve` ENUM( '0', '1' ) NOT NULL ,
PRIMARY KEY ( `tid` )
)De `tid` (to ID) verwijst naar de gebruiker en de rest spreekt voor zich.
Stel Klaas mag:
- [li]Nieuws toevoegen[/li][li]Nieuws wijzigen[/li][li]Games wijzigen[/li][li]Games verwijderen[/li]
Dan zou een rij in deze kolom er als volgt uit zien:
tid news_add news_edit news_delete news_approve games_add games_edit games_delete games_approve
25 1 1 0 0 0 1 1 0Stel dat Klaas nu op 'wijzigen' klikt. Dan zou dat er in PHP zo uit moeten zien:
<?php
// connect to database
include('includes/database.inc.php');
// retrieve the rights
$rights_sql = "SELECT * FROM user_rights WHERE tid = " . mysql_real_escape_string($_SESSION['user_id']);
if (!$rights_res = mysql_query($rights_sql))
trigger_error('Fout in query: ' . mysql_error());
else
{
if (mysql_num_rows($rights_res) >= 1)
$rights = mysql_fetch_assoc();
}
// the different pages
if ($_GET['show'] == 'nieuws')
{
// add
if ($_GET['page'] == 'add' && $rights['news_add'] == 1)
echo 'Add news';
elseif ($_GET['page'] == 'edit' && $rights['news_edit'] == 1)
echo 'Edit news';
elseif ($_GET['page'] == 'delete' && $rights['news_delete'] == 1)
echo 'Delete news';
elseif ($_GET['page'] == 'approve' && $rights['news_approve'] == 1)
echo 'Approve news';
else
echo 'Show overview news items';
}
elseif ($_GET['show'] == 'games')
{
if ($_GET['page'] == 'add' && $rights['games_add'] == 1)
echo 'Add a game';
elseif ($_GET['page'] == 'edit' && $rights['games_edit'] == 1)
echo 'Edit a game';
elseif ($_GET['page'] == 'delete' && $rights['games_delete'] == 1)
echo 'Delete';
elseif ($_GET['page'] == 'approve' && $rights['games_approve'] == 1)
echo 'Approve a game';
else
echo 'Show overview with games';
}?>
Dit is een erg simpele manier om het te doen. Eéntje die ik ook vaak tegen kom en werkt, maar niet optimaal is. Stel nu dat een gebruiker die games mag verwijderen, ze ook automatisch mag toevoegen, wijzigen en goed mag keuren? Dan krijg je in PHP iets als:
<?php
if ($_GET['show'] == 'games')
{
if ($_GET['page'] == 'add' && ($rights['games_add'] == 1 || $rights['games_delete'] == 1))
echo 'Add a game';
elseif ($_GET['page'] == 'edit' && ($rights['games_edit'] == 1 || $rights['games_delete'] == 1))
echo 'Edit a game';
// etc
?>
Stel nu dat gebruikers die mogen wijzigen, ook mogen toevoegen, dan kun je erg lange if statements krijgen. Dit is niet het geval als je de bitwise methode gebruikt. Zie de volgende pagina voor uitleg.
Pagina 3
Bitwise rechten systeem
We gaan weer uit van de zelfde situatie. Een website met nieuws en games waarbij je per pagina de functionaliteiten; toevoegen, wijzigen, verwijderen en goedkeuren hebt.
Door het gebruik van bitwise kun je functionaliteiten opslaan in bits. Een systeem zoals we op de vorige pagina bespraken, zou je als volgt definiëren in je config file:
<?php
include('includes/database.inc.php');
// set permissions
$rights['news_add'] = 1;
$rights['news_edit'] = 2;
$rights['news_delete'] = 4;
$rights['news_approve'] = 8;
$rights['games_add'] = 16;
$rights['games_edit'] = 32;
$rights['games_delete'] = 64;
$rights['games_approve'] = 128;
?>
We hebben nu de rechten in bitwise gezet.
Stel dat Klaas nu de rechten heeft om een game toe te voegen. In dit geval is Klaas zijn recht: 16. Dit zetten we voor het gemak in $_SESSION['myrights']. In PHP controleer je dit op de volgende manier:
<?php
if ($_GET['show'] == 'games')
{
// if (website.php?show=games&page=add && 16 & 16)
if ($_GET['page'] == 'add' && $_SESSION['myrights'] & $rights['games_add'])
echo 'Add a game';
else
echo 'Wrong rights..';
}
?>
Stel nu dat Klaas een game wil verwijderen:
<?php
if ($_GET['show'] == 'games')
{
// if (website.php?show=games&page=delete && 16 & 64)
if ($_GET['page'] == 'delete' && $_SESSION['myrights'] & $rights['games_delete'])
echo 'Delete a game';
else
echo 'Wrong rights..'; // this will get triggered
}
?>
Of dat hij een nieuws artikel wil toevoegen:
<?php
if ($_GET['show'] == 'news')
{
// if (website.php?show=news&page=add && 16 & 1)
if ($_GET['page'] == 'add' && $_SESSION['myrights'] & $rights['news_add'])
echo 'Add news';
else
echo 'Wrong rights..'; // this will get triggered
}
?>
Een ander voorbeeld. Stel dat Klaas nu nieuws mag toevoegen en wijzigen. Ook mag hij games verwijderen en goedkeuren. Dan tel je de getallen van de rechten op, in dit geval:
<?php
$rights['news_add'] = 1;
$rights['news_edit'] = 2;
$rights['games_delete'] = 64;
$rights['games_approve'] = 128;
?>
Je telt dus: 1 + 2 + 64 + 128 = 195.
Klaas heeft in zijn gebruikers tabel een kolom genaamd 'myrights'. Dat is in dit geval dus; 195. We zetten dit voor het gemak weer even in $_SESSION['myrights'].
Stel nu dat er een actie uitgevoerd moet worden voor het verwijderen van een game. In PHP ziet dit er dan als volgt uit:
<?php
if ($_GET['show'] == 'games')
{
// if (website.php?show=games&page=delete && 195 & 64)
if ($_GET['page'] == 'delete' && $_SESSION['myrights'] & $rights['games_delete'])
echo 'Delete it!';
else
echo 'Wrong rights..';
}
?>
Wat doen we hier nu boven? Ten eerste kijk je of de 'delete' pagina wordt aangeroepen. Zo ja, dan ga je kijken of de rechten van Klaas, in dit voorbeeld 195 een bit zijn van 64. Dat is in dit geval dus juist.
Dit principe kun je ook koppelen aan groepen. Stel je hebt een groep gamers die alles mogen doen op de 'games' pagina (toevoegen, wijzigen, verwijderen, goedkeuren). Dan zou je een database tabel moeten aanmaken voor de groepen met daarin de integer: 240 (optelling van: games_add + games_edit + games_delete + games_approve). Vervolgens koppel je de gebruiker aan de ID van de groep en klaar is Klaas in dit geval. :)
Voor je hele rechten systeem heb je dus maar 1 integer per gebruiker nodig om te bepalen wat hij of zij wel en niet mag. Hoop dat je er wat van hebt kunnen opsteken en dat ik het goed heb uitgelegd. Vragen graag per reactie.
Door het gebruik van bitwise kun je functionaliteiten opslaan in bits. Een systeem zoals we op de vorige pagina bespraken, zou je als volgt definiëren in je config file:
<?php
include('includes/database.inc.php');
// set permissions
$rights['news_add'] = 1;
$rights['news_edit'] = 2;
$rights['news_delete'] = 4;
$rights['news_approve'] = 8;
$rights['games_add'] = 16;
$rights['games_edit'] = 32;
$rights['games_delete'] = 64;
$rights['games_approve'] = 128;
?>
We hebben nu de rechten in bitwise gezet.
Stel dat Klaas nu de rechten heeft om een game toe te voegen. In dit geval is Klaas zijn recht: 16. Dit zetten we voor het gemak in $_SESSION['myrights']. In PHP controleer je dit op de volgende manier:
<?php
if ($_GET['show'] == 'games')
{
// if (website.php?show=games&page=add && 16 & 16)
if ($_GET['page'] == 'add' && $_SESSION['myrights'] & $rights['games_add'])
echo 'Add a game';
else
echo 'Wrong rights..';
}
?>
Stel nu dat Klaas een game wil verwijderen:
<?php
if ($_GET['show'] == 'games')
{
// if (website.php?show=games&page=delete && 16 & 64)
if ($_GET['page'] == 'delete' && $_SESSION['myrights'] & $rights['games_delete'])
echo 'Delete a game';
else
echo 'Wrong rights..'; // this will get triggered
}
?>
Of dat hij een nieuws artikel wil toevoegen:
<?php
if ($_GET['show'] == 'news')
{
// if (website.php?show=news&page=add && 16 & 1)
if ($_GET['page'] == 'add' && $_SESSION['myrights'] & $rights['news_add'])
echo 'Add news';
else
echo 'Wrong rights..'; // this will get triggered
}
?>
Een ander voorbeeld. Stel dat Klaas nu nieuws mag toevoegen en wijzigen. Ook mag hij games verwijderen en goedkeuren. Dan tel je de getallen van de rechten op, in dit geval:
<?php
$rights['news_add'] = 1;
$rights['news_edit'] = 2;
$rights['games_delete'] = 64;
$rights['games_approve'] = 128;
?>
Je telt dus: 1 + 2 + 64 + 128 = 195.
Klaas heeft in zijn gebruikers tabel een kolom genaamd 'myrights'. Dat is in dit geval dus; 195. We zetten dit voor het gemak weer even in $_SESSION['myrights'].
Stel nu dat er een actie uitgevoerd moet worden voor het verwijderen van een game. In PHP ziet dit er dan als volgt uit:
<?php
if ($_GET['show'] == 'games')
{
// if (website.php?show=games&page=delete && 195 & 64)
if ($_GET['page'] == 'delete' && $_SESSION['myrights'] & $rights['games_delete'])
echo 'Delete it!';
else
echo 'Wrong rights..';
}
?>
Wat doen we hier nu boven? Ten eerste kijk je of de 'delete' pagina wordt aangeroepen. Zo ja, dan ga je kijken of de rechten van Klaas, in dit voorbeeld 195 een bit zijn van 64. Dat is in dit geval dus juist.
Dit principe kun je ook koppelen aan groepen. Stel je hebt een groep gamers die alles mogen doen op de 'games' pagina (toevoegen, wijzigen, verwijderen, goedkeuren). Dan zou je een database tabel moeten aanmaken voor de groepen met daarin de integer: 240 (optelling van: games_add + games_edit + games_delete + games_approve). Vervolgens koppel je de gebruiker aan de ID van de groep en klaar is Klaas in dit geval. :)
Voor je hele rechten systeem heb je dus maar 1 integer per gebruiker nodig om te bepalen wat hij of zij wel en niet mag. Hoop dat je er wat van hebt kunnen opsteken en dat ik het goed heb uitgelegd. Vragen graag per reactie.
Reacties
0