Jogosultság kezelés
Egyik korábbi cikkünkben a munkamenet illetve a felhasználó kezelés rejtelmeiről volt szó. Ehhez szorosan kapcsolódik a mai témánk: a jogosultság kezelés. Ez egy mini sorozat első fejezete lesz, mely az előzetes tervek szerint két részből fog állni. Az elsőben egy alap rendszert valósítunk meg, majd a következőben megvizsgáljuk, hogy hogyan tudjuk ezt kiegészíteni összetett (attribútumokkal rendelkező) jogosultságok kezelésének képességével.
A fenti alapján a következő logikai adatbázisterv adódik:
Az ábrán még feltüntettem a munkamenet kezeléshez szükséges táblát is, melynek majd még a jogosultságok kezelése kapcsán is szerepe lesz. A táblák nevei értelemszerűen jelölik, hogy milyen adatokat tárolunk bennük. A mezők melletti adattípusok szintén logikai adattípusok. A táblák közötti kapcsolatok jelzik, hogy azok milyen viszonyban vannak egymással. Például a felhasználó csoportokat a
A megvalósításhoz én a PostgreSQL-t választottam, mely manapság az egyik legjobb nyílt forrás kódú adatbázis kezelő rendszer, és sajnos méltatlanul van háttérbe szorítva a MySQL által, melyet mind funkcionalitásában, az SQL szabvány követésében, megbízhatóságban és konfigurálhatóságában messze leköröz. Látni fogjuk, hogy például hogyan használhatunk triggereket adatbázisunk konzisztenciájának biztosítására.
A választásból fakadóan a következő fizikai adatbázis tervet kapjuk:
Mint láthatjuk a logikai terv kapcsolatai a számosságuktól függően külön táblákra, a logikai adattípusok pedig a megfelelő PostgreSQL adattípusra képződtek le. Ezen az ábrán a táblák közötti nyilak hivatkozási épség megszorításokat (foreign key constraint) jelölnek. Ezek használatával biztosíthatjuk, hogy például egy csoport tagja csak egy létező felhasználó lehessen (a
A fenti ábra alapján kapjuk a következő adatbázis sémát:
Van még azonban egy kis disznóság, amivel nem foglalkoztunk. Mint említettem korábban, lehetőségünk van az egyes felhasználóknak extra jogokat biztosítani, illetve jogokat megvonni tőlük. Ezek tárolására szolgál azA fenti kód két triggert (http://www.postgresql.org/docs/8.0/interactive/triggers.html) definiál. Ezek a triggerek PL/pgSQL függvények, melyek a két táblán történő minden egyes
A jogosultságokat a következő lekérdezés adja vissza:A bejelentkezés a következő képpen nézhet ki:Ezt követően a jogosultságait nem frissítjük minden egyes oldallekéréskor, egy felesleges adatbázis műveletet végrehajtva. Ennek a módszernek azonban egy hátulütője lehet, miszerint ha egy felhasználónak a bejelentkezését követően megváltoznak a jogosultságai (az adminisztrátor éppen ezen idő alatt módosítja őket), akkor a frissítés nélkülözése miatt a munkamenetében és az adatbázisban tárolt jogai nem lesznek összhangban, a felhasználó esetleg továbbra is elérhet olyan funkciókat, melyekhez szükséges jogosultságokat már megvonták tőle.
A problémát úgy hidaltam át, hogy a munkamenet kezelésbe építettem bele egy, ezt a szituációt jelző funkciót. A munkameneteket tároló adatbázis táblába bekerült egy plusz mező (Persze tárolhattam volna magukat az így képzett szövegeket is a munkamenetben, és használhattam volna őket a jogosultság meglétének vizsgálatakor, de ennek két hátránya is lett volna: sok jog esetén lényeges különbség van a tárolt adatmennyiség között, de ennél is fontosabb, hogy ha egy konstans nevét írom el, akkor arról egy PHP figyelmeztetés formájában azonnal értesülök, míg ha egy szövege literált gépelek el, akkor nem, sokkal nehezebben találom meg a hibát.
■ Miért van rá szükségünk
A webes alkalmazások többségénél szükségünk van arra, hogy felhasználóinkat megkülönböztethessük abból a szempontból, hogy milyen viszonyban állnak rendszerünkkel, mely funkcióit használhatják. E cél érdekében használunk jogosultság rendszert: minden egyes felhasználó esetén meghatározzuk, hogy milyen interakciókra van lehetősége alkalmazásunkkal szemben. Például egy fórum esetén egy (jogosultsággal nem rendelkező) látogató csak olvashatja a hozzászólásokat, egy regisztrált ("bejelentkezett" jogosultsággal rendelkező) tag hozzászólhat a fórum témákhoz, vagy újakat hozhat létre, míg egy adminisztrátor jogosultságokkal rendelkező felhasználó moderálhatja a többiek hozzászólásait, létrehozhat új fórum kategóriákat, stb..Jogosultságok típusai
A jogosultságok esetén én két alapvető esetet különböztetnék meg. Vannak olyan jogosultságok, melyek esetében a puszta létük hordoz információt. Például egy cikk szerkesztő jogosultsággal rendelkező felhasználónak joga van publikálni. Általában az ilyen jogosultságok használata elegendő rugalmasságot biztosít számunkra. (De a törpök élete nem csak játék és mese.) Előfordulhatnak olyan szituációk, amikor ez kevésnek bizonyul, például szeretnénk, ha minden felhasználó csak az általa létrehozott cikkeket tudná szerkeszteni. Egy ilyen esetben a jogosultságot egy függvényként foghatjuk fel, mely az aktuális paraméterek (cikk, felhasználó azonosító) birtokában képes eldönteni, hogy a felhasználó a kívánt funkció elérésére ténylegesen jogosult-e vagy sem. Ezeket hívtam a bevezetőben összetett jogosultságoknak, és ezek támogatásáról lesz szó a következő részben.A jogosultság rendszer felépítése
Először is vegyük sorra, hogy alap rendszerünk esetén milyen entitások kapnak szerepet: modul, jogosultság, felhasználó, csoport. Alkalmazásunk modulokból áll. A jogosultságok mindig egy modulhoz kötődnek, mindegyik modul meghatározza, hogy esetében mely jogok definiáltak. A felhasználókat csoportokba szervezhetjük a jogosultság kezelés menedzselésének egyszerűsítése végett. Ennek érdekében egy csoportba tehetjük az azonos feladatokat ellátó felhasználókat, és elegendő csak az adott csoporthoz hozzárendelni az adott feladat elvégzéséhez szükséges jogosultságokat, nem pedig egyenként, mindegyik felhasználóhoz. Természetesen egy felhasználó több csoportnak is tagja lehet. Ezenkívül az árnyaltabb kialakítás érdekében lehetőségünk van az egyes felhasználókhoz külön jogokat adni vagy elvenni a csoportjogokhoz képest. Ha alkalmazásunk rétegzettsége megkívánja, indokolt lehet annak megvalósítása is, hogy a csoportok más csoportokat is tartalmazhassanak, de ettől mi most eltekintünk.A fenti alapján a következő logikai adatbázisterv adódik:
Logikai adatbázisterv
Az ábrán még feltüntettem a munkamenet kezeléshez szükséges táblát is, melynek majd még a jogosultságok kezelése kapcsán is szerepe lesz. A táblák nevei értelemszerűen jelölik, hogy milyen adatokat tárolunk bennük. A mezők melletti adattípusok szintén logikai adattípusok. A táblák közötti kapcsolatok jelzik, hogy azok milyen viszonyban vannak egymással. Például a felhasználó csoportokat a
members
kapcsolat definiálja.A megvalósításhoz én a PostgreSQL-t választottam, mely manapság az egyik legjobb nyílt forrás kódú adatbázis kezelő rendszer, és sajnos méltatlanul van háttérbe szorítva a MySQL által, melyet mind funkcionalitásában, az SQL szabvány követésében, megbízhatóságban és konfigurálhatóságában messze leköröz. Látni fogjuk, hogy például hogyan használhatunk triggereket adatbázisunk konzisztenciájának biztosítására.
A választásból fakadóan a következő fizikai adatbázis tervet kapjuk:
Fizikai adatbázisterv
Mint láthatjuk a logikai terv kapcsolatai a számosságuktól függően külön táblákra, a logikai adattípusok pedig a megfelelő PostgreSQL adattípusra képződtek le. Ezen az ábrán a táblák közötti nyilak hivatkozási épség megszorításokat (foreign key constraint) jelölnek. Ezek használatával biztosíthatjuk, hogy például egy csoport tagja csak egy létező felhasználó lehessen (a
members
tábla mem_u_id
oszlopába csak olyan érték szúrható be, amilyen érték szerepel a users
tábla u_id
oszlopában), vagy hogy egy csoportot ne lehessen addig törölni, amíg van tagja.A fenti ábra alapján kapjuk a következő adatbázis sémát:
/*==============================================================*/
/* DBMS name: PostgreSQL 7.3 */
/* Created on: 2005.02.02. 03:45:03 */
/*==============================================================*/
/*==============================================================*/
/* Table: denied_rights */
/*==============================================================*/
create table denied_rights (
u_id INT4 not null,
rgt_id INT4 not null,
constraint denied_rights_pk primary key (u_id, rgt_id)
);
/*==============================================================*/
/* Table: extra_rights */
/*==============================================================*/
create table extra_rights (
u_id INT4 not null,
rgt_id INT4 not null,
constraint extra_rights_pk primary key (u_id, rgt_id)
);
/*==============================================================*/
/* Table: group_rights */
/*==============================================================*/
create table group_rights (
grp_id INT4 not null,
rgt_id INT4 not null,
constraint group_rights_pk primary key (grp_id, rgt_id)
);
/*==============================================================*/
/* Table: groups */
/*==============================================================*/
create table groups (
id SERIAL not null,
name VARCHAR(25) not null,
dscr VARCHAR(255) null,
constraint groups_pk primary key (id)
);
/*==============================================================*/
/* Index: groups_dscr_uk */
/*==============================================================*/
create unique index groups_name_uk on groups (
name
);
/*==============================================================*/
/* Table: members */
/*==============================================================*/
create table members (
u_id INT4 not null,
grp_id INT4 not null,
constraint members_pk primary key (u_id, grp_id)
);
/*==============================================================*/
/* Table: modules */
/*==============================================================*/
create table modules (
id SERIAL not null,
name VARCHAR(25) null,
constraint modules_pk primary key (id)
);
/*==============================================================*/
/* Index: modules_name_uk */
/*==============================================================*/
create unique index modules_name_uk on modules (
name
);
/*==============================================================*/
/* Table: rights */
/*==============================================================*/
create table rights (
id SERIAL not null,
name VARCHAR(25) not null,
mod_id INT4 not null,
const VARCHAR(50) null,
dscr VARCHAR(255) null,
set_act VARCHAR(25) null,
constraint rights_pk primary key (id)
);
/*==============================================================*/
/* Index: module_rights_fk */
/*==============================================================*/
create index module_rights_fk on rights (
mod_id
);
/*==============================================================*/
/* Index: rights_name_mod_id_uk */
/*==============================================================*/
create unique index rights_name_mod_id_uk on rights (
name, mod_id
);
/*==============================================================*/
/* Index: rights_name_mod_id_uk */
/*==============================================================*/
create unique index rights_const_uk on rights (
const
);
/*==============================================================*/
/* Table: user_sessions */
/*==============================================================*/
create table user_sessions (
id SERIAL not null,
session_id VARCHAR(32) not null,
u_id INT4 not null,
ip_address VARCHAR(23) not null,
user_agent VARCHAR(255) null,
referer VARCHAR(255) null,
created TIMESTAMP not null,
modified TIMESTAMP not null,
rights_changed BOOL null,
constraint user_sessions_pk primary key (id)
);
/*==============================================================*/
/* Index: us_session_id_uk */
/*==============================================================*/
create unique index user_sessions_session_id_uk on user_sessions (
session_id
);
/*==============================================================*/
/* Index: us_u_id_uk */
/*==============================================================*/
create unique index user_sessions_u_id_uk on user_sessions (
u_id
);
/*==============================================================*/
/* Table: users */
/*==============================================================*/
create table users (
id SERIAL not null,
forename VARCHAR(25) not null,
surname VARCHAR(25) not null,
email VARCHAR(100) not null,
login VARCHAR(10) not null,
password VARCHAR(32) not null,
temppass VARCHAR(32) null,
created DATE not null,
constraint users_pk primary key (id)
);
/*==============================================================*/
/* Index: users_u_login_uk */
/*==============================================================*/
create unique index users_login_uk on users (
login
);
/*==============================================================*/
/* Index: users_u_email_uk */
/*==============================================================*/
create unique index users_email_uk on users (
email
);
alter table denied_rights
add constraint fk_denied_right foreign key (rgt_id)
references rights (id)
on delete cascade on update restrict;
alter table denied_rights
add constraint fk_has_denied_right foreign key (u_id)
references users (id)
on delete cascade on update restrict;
alter table extra_rights
add constraint fk_extra_right foreign key (rgt_id)
references rights (id)
on delete cascade on update restrict;
alter table extra_rights
add constraint fk_has_extra_right foreign key (u_id)
references users (id)
on delete cascade on update restrict;
alter table group_rights
add constraint fk_group_right foreign key (rgt_id)
references rights (id)
on delete cascade on update restrict;
alter table group_rights
add constraint fk_has_group_right foreign key (grp_id)
references groups (id)
on delete cascade on update restrict;
alter table members
add constraint fk_is_member foreign key (u_id)
references users (id)
on delete cascade on update restrict;
alter table members
add constraint fk_has_user foreign key (grp_id)
references groups (id)
on delete cascade on update restrict;
alter table rights
add constraint fk_module_rights foreign key (mod_id)
references modules (id)
on delete cascade on update restrict;
alter table user_sessions
add constraint fk_session_belong_to_user foreign key (u_id)
references users (id)
on delete cascade on update restrict;
Adatbázis konzisztencia
A fenti SQL script az ábrán szereplő elemeken kívül tartalmaz még pár egyediségre vonatkozó megszorítást (unique constraint). Ezek logikus megszorítások (például nem lehet két azonos nevű modul), melyek mind védik adatbázisunkat, hogy ne kerülhessenek bele inkonzisztens adatok.Van még azonban egy kis disznóság, amivel nem foglalkoztunk. Mint említettem korábban, lehetőségünk van az egyes felhasználóknak extra jogokat biztosítani, illetve jogokat megvonni tőlük. Ezek tárolására szolgál az
extra_rights
és a denied_rights
tábla. Elvileg megtehetjük, hogy egy adott jogosultságot mindkét táblában szerepeltetünk egy adott felhasználó esetén, ami nem túl szerencsés. Ennek kivédésére bővítsük ki a fenti sémát az alábbi kóddal: CREATE FUNCTION checkIfExtraRightExists() RETURNS TRIGGER AS '
DECLARE
id INTEGER;
BEGIN
SELECT INTO id u_id FROM extra_rights WHERE u_id = new.u_id AND rgt_id = new.rgt_id;
IF FOUND THEN
RAISE EXCEPTION ''existing_extra_right_exception'';
RETURN null;
ELSE
RETURN new;
END IF;
END;
' LANGUAGE 'plpgsql';
CREATE TRIGGER denied_rights_chk
BEFORE INSERT OR UPDATE
ON denied_rights
FOR EACH ROW EXECUTE PROCEDURE checkIfExtraRightExists();
CREATE FUNCTION checkIfDeniedRightExists() RETURNS TRIGGER AS '
DECLARE
id INTEGER;
BEGIN
SELECT INTO id u_id FROM denied_rights WHERE u_id = new.u_id AND rgt_id = new.rgt_id;
IF FOUND THEN
RAISE EXCEPTION ''existing_denied_right_exception'';
RETURN null;
ELSE
RETURN new;
END IF;
END;
' LANGUAGE 'plpgsql';
CREATE TRIGGER extra_rights_chk
BEFORE INSERT OR UPDATE
ON extra_rights
FOR EACH ROW EXECUTE PROCEDURE checkIfDeniedRightExists();
INSERT
és UPDATE
parancs esetén meghívódnak, és a visszatérési értékük határozza meg, hogy ezek az SQL utasítások ténylegesen érvényre jutnak-e vagy sem. A függvényben ellenőrizzük, hogy a másik táblában szerepel-e ugyanazon felhasználóhoz hozzárendelve az adott jogosultság, és ha találunk ilyen sort, akkor egy kivételt váltunk ki. Az itt megadott szöveg szerepelni fog a PHP-nak visszaadott hibaüzenetben, így szükség szerint a hibát szépen le tudjuk kezelni.Jogosultság rendszer használata
Amikor a felhasználó bejelentkezik a rendszerbe, jogosultságai felolvasásra kerülnek az adatbázisból, és aUser
objektumban tárolva bekerülnek a munkamenetében tárolt adatok közé. Ez a User
objektum a mindenkori látogatót testesíti meg. Számunkra fontos tulajdonsága, hogy képes megmondani, hogy a felhasználó be van-e jelentkezve (isLogged()
), illetve, hogy rendelkezik-e egy megadott jogosultsággal vagy sem (hasRight()
).A jogosultságokat a következő lekérdezés adja vissza:
SELECT
r.id
FROM
users u
JOIN
members m ON m.u_id = u.id
JOIN
groups g ON g.id = m.grp_id
JOIN
group_rights i ON i.grp_id = g.id
JOIN
rights r ON r.id = i.rgt_id
LEFT JOIN
denied_rights d ON (r.id = d.rgt_id AND d.u_id = '.$userId.')
WHERE
u.id = '.$userId.' AND d.u_id is null
UNION
SELECT
r.id
FROM
rights r
JOIN
extra_rights e ON r.id = e.rgt_id
WHERE
e.u_id = '.$userId.'
<?php
$dao =& DaoFactory::get('Login');
// Login név, jelszó ellenőrzése
if (null !== ($userInfo =& $dao->getUserInfoByLogin($request->getParam('loginName'), $request->getParam('password')))) {
// Beállítjuk a felhasználó adatait
$user->setLoginState(true);
$user->setData('userInfo', $userInfo);
$dao =& DaoFactory::get('Rights');
// Elmentjük a felhasználó jogosultságait
$user->setRights($dao->getUserRights($userInfo['id']));
} else {
$request->setError('login', 'A megadott bejelentkezési név vagy a jelszó nem megfelelő!');
}
?>
A problémát úgy hidaltam át, hogy a munkamenet kezelésbe építettem bele egy, ezt a szituációt jelző funkciót. A munkameneteket tároló adatbázis táblába bekerült egy plusz mező (
us_rights_changed
), melyet true
értékre állítva jelezhetjük, hogy szükséges a jogosultságok újraolvasása. Ezt a táblát úgyis szükséges minden egyes oldal kérés esetén kiolvasnunk a munkamenet ellenőrzése érdekében. Amikor az adminisztrációs felületen keresztül megváltoztatjuk a jogosultságokat, akkor az ezt érintő felhasználók azonosítója alapján lefut egy update a munkamenet táblán és beállítja ezt a mezőt.Jogosultságok ellenőrzése
A felhasználó munkamenetében konkrétan az általa birtokolt jogosultságok (adatbázis) azonosítói kerülnek tárolásra. Ezt követően bármikor használhatjuk aUser
objektum hasRight()
függvényét annak megállapítására, hogy a felhasználó rendelkezik-e egy joggal, vagy sem. A függvény egy jogosultság azonosítót vár paraméterül, ami ugye egy szám. Egy ilyen szám kifejező ereje viszont elég kicsi, nehezen tudnánk megjegyezni, hogy mondjuk a cikkek törlésének jogosultsága az éppen mennyi is, ezért ezen probléma orvoslására a következőt találtam ki. Amikor a jogosultságokat rögzítjük a rendszerbe, meg kell adjunk egy modul szinten egyedi szöveget (az egyediség adatbázis szinten biztosított), ami szintén tárolásra kerül. Ez alapján modulonként generálhatunk egy file-t, ami ezen szövegek, a modul neve és egy prefix (RIGHT_
) alapján képzett konstans definíciókat tartalmaz, mely konstansok értéke az adott jogosultság azonosítója. Ezen file-ok generálása és includolása könnyedén automatizálható. Ezt követően például egy cikk törlésének jogosultságát a következőképpen ellenőrizhetjük:<?php
if ($user->hasRight(RIGHT_ARTICLE_DELETE) {
// Cikk törlése
} else {
$request->setError('articleDelete', 'Sorry, nincs jogosultságod a cikk törléséhez!');
$request->setError('articleDelete', 'És semmi légyszi, légyszi, légyszi!');
}
?>
Utolsó simítások ;)
Ezek után már csak annyit kell tennünk, hogy összedobunk egy kis adminisztrációs felületet, mellyel a fenti adatbázist szerkeszteni tudjuk. Igazából ebben túl nagy kihívás nincs, egy kis rabszolga munka az egész, ki-ki végezze el kedve szerint. Egy érdekesebb lekérdezést még megosztok, mellyel azokat a jogosultságokat kérdezhetjük le, melyek még nincsenek hozzárendelve egy adott felhasználóhoz (jól jöhet az adminhoz :))SELECT
r.id, r.name, r.mod_id, m.name as mod_name
FROM
rights r
LEFT JOIN
denied_rights d
ON (r.id = d.rgt_id AND d.u_id = '.$userId.')
LEFT JOIN
extra_rights e
ON (r.id = e.rgt_id AND e.u_id = '.$userId.')
JOIN
modules m
ON r.mod_id = m.id
WHERE
d.u_id is null AND e.u_id is null
ORDER BY
m.name, r.name;
extra - denied rights
Jogos
Jogos az eszrevetel. A nagy Powerdesignerosdiban nem is jutott ez eszembe. Tenyleg egyszrubb lenne igy, bar teljesitmeny szempontjabol nagyjabol mindegy.
Koszi,
Felho
Mikor lesz folytatás?
Kb. 3 het
Elorelathatolag 2 het mulva jon a folytatas, de ez meg tobb dologtol is fugghet. ;)
Felho
Kösz
Tűkön ülök ^^
Tényleg nem akarok pofátlan lenni, de igen érdekelne a cikk folytatása. Nem fogok ezzel tolakodni a jövőben, csak egy utolsó segélykiáltást hallattam... ,)
Folytatás?
nem derült ki itt a válaszokból, hogy megjelent-e a folytatás, vagy nem.
Lehet még rá számítani?
Üdv: Sparrow
nem túl esélyes
Login elötti user_id
Nem kapcsolódik szorosan a témához, de mivel megláttam az adatmodellben egy olyan problémát amivel magam is gyakran szembesülök.
Mert ügyebár a ForeginKey nem engedi üresen hagyni.
Ha a USERS táblába insertálok egy rekordod, (legyen mondjuk ez az első, tehát id=1)
akkor figyelnem kell arra, hogy ne tudjon bejelentkezni, ne küldjek neki levelet, ne számoljam a tagok közé, stb...
Ha nincsen ForeginKey akkor Trigger-rel kell figyelgetni hogy csak 0(nulla) vagy csak olyan érték legyen ami szerepel a USERS táblában.
MySQL 4.x estében úgy is programozni kell, de én is egyre jobban favorizálom a PostgreSQL-t
Eddig is megoldottam, csak gondoltam megkérdezem hátha tudtok valami jó Barba trükköt.
Szívesen veszem a javaslatokat.
Jó munkát
ui.:
Ez miért kell a USERS_SESSIONS táblába?
id SERIAL not null,
A session_id miért nem elég?
Adatmodell
A cikkben látható adatmodell ábrákat valami adatmodellező programmal csináltad vagy csak valami grafikaival? Ha adatmodellező akkor melyik... Esetleg más adatmodellező progikat ismertek?
Elöre is köszi:
Nova
PowerDesigner
Az ábrák a Sybase PowerDesigner nevű programjával készültek. Szerintem az egyik legjobb adatbázis tervező progi, érdemes kipróbálni. Egyetlen nagy baja az ára sajnos.
Érdemes talán megnézni az EMS termékeket, ezek már mind tartalmaznak grafikus tervező funkciót is, bár ebben a fenti cucctól erősen elmaradnak.
Aztán még van pár megoldás érdmes kicsit szétnézni.
Felhő
Designer
http://sourceforge.net/projects/druid/ én ezt használom
http://sourceforge.net/projects/mogwai/
de van még néhány
Kérdések
1. A rights táblában mi a célod a const, set_act mezőkkel. Ezek gondolom a jogosultság tulajdonságait határozzák meg.
2. A másik kérdés nagyon alap. Hogyan kötöd ezt az egészet a kódodhoz? A modul kifejezés programmodult jelent? Végül is itt programmodulok futtatásához való jogokról van szó?
Észrevettem egy hibát, vagy
Egyébként érdekelne, hogy ki hogyan tárolja a munkameneteket, leginkább az, hogy nem e túl lassú, ha adatbázisban tárolja őket az ember. Éppen ajax-os projektet csinálok, és erősen gondolkodom rajta, hogy adatbázisba tegyem a munkameneteket fájlrendszer helyett, hogy véletlenül se legyen concurrency-vel kapcsolatos gond ...
Egyébként annyi könnyebbség van a single page js-es oldalakkal, hogy csak a jogosultságot kell tárolni munkamenetben, ezért a rights_changed flag is kihagyható az adatbázisból, és közvetlenül össze lehet kötni a rights-ot a sessions-el. Php-s szerializálásra sincs így szükség. Hát akkor tényleg ez lesz, és adatbázis szerverrel ellenőriztetek majd jogosultságot a php-s cache helyett. Amúgy ezt ugyanúgy meg lehet csinálni, ha más adat is van a session-ben, így a jogokat nem kell újra és újra szerializáltatni a php-vel...
Valaki leírná egybe és
jogosultság.sql
nem.
Mi ez?!
Tegyél fel értelmes kérdést, erre nem tudunk válaszolni (én legalábbis).
Azt szeretném hogy egybe
pl ezt taRTALMAZZA adatbázis.sql
ezt a jogosultság.sql:
ezt mindenki
menü1 menü 2 menü5 stb
ezt csak aki bejelentkezik (normál felhasználó).../csoport2
menü3 menü6 menü7(+ azok a menüpontok amiket mindenki lát)
Ezt a V.I.P.-tagok:
menü7 menü8 menü9 menü10((+ azok a menüpontok amiket mindenki és a normál felhasználok látnak látnak)
Anminisztrátor(Tulaj):
mindent
Moderátor:
mindent
És senki sem látja (csak az admin) a adninisztrátor belépés menü pontot
Remélem mostmár valamennyivel érthetőbb...
Adatbázis