Hi

Ik zit er aan te denken om nog eens wat in PHP te gaan doen. Als basis wil ik eerst en vooral een degelijk 'usermangement system' opzetten. Dit in een object gericht concept.

Omdat hierbij zowel het databaseontwerp als het implementeren van de code zelf belangrijk zijn, zou ik deze graag beiden bespreken.

De database zou ik als volgt willen inrichten:


Misschien kort even het schema toelichten:
In de database wordt over elke gebruiker wat basisgegevens bijgehouden. Er kunnen eventueel een aantal opmerkingen gemaakt worden over een gebruiker. (bv. zijn specifieke functie op de website). Verder is er verplicht een koppeling met de permissies tabel. Uiteraard, behoord een 'permissie-entry' altijd aan 1 specifieke gebruiker. (kleine opmerking hieronder) Verder worden alle belangrijke zaken die een gebruiker uitvoert gelogd. Tot slot is er nog een tabel met sessies in (Ik ben van plan een eigen session handler te programmeren die via de database werkt.) Elke sessie verwijst naar 1 gebruiker.

[opmerking permissies]
Ik overweeg dit nog wat aan te passen, namelijk een toevoeging: groups. Elke gebruiker krijgt dan een group en een group krijgt op zijn beurt een aantal permissies.

In PHP zou ik dan volgende klassen bekomen:
Session, User, Log, Note. Wat deze doen, lijkt mij vanzelfsprekend. Indien dat niet het geval zou zijn, wil ik dit gerust even toelichten.

Graag jullie mening over dit 'model'!
Hmm, aangezien de code wat groter werd dan verwacht heb ik het even gezipt, kijk er maar in en zoek eerst zelf wat op als je iets niet begrijpt en vraag het daarna anders hier. En het is nog niet getest, dus er kunnen fouten in zitten. Soms bestaan sommige dingen ook niet, dit is slechts de basis zodat jij het kunt begrijpen.

http://phphulp.wouterj.nl/usermanagement.zip
Wouter, bedankt! Inderdaad een duidelijk voorbeeld. Ik moet wel nog even uitzoeken hoe dat met die namespaces zit, nooit eerder gebruikt. Maar goed, dat lukt vast en zeker wel.

Toch nog een paar vragen. Een gebruiker logt in, wat is de beste manier om dan te bepalen wat voor een gebruiker hij is? Want met jouw voorbeeld, maak je dus voor een admin een ander object aan dan voor een user. Ik denk ook als deze vraag beantwoord is, dat mijn 2de vraag beantwoord zal zijn: wat is het nut van Guest, aangezien die toch geen rechten heeft.
Je logt de gebruiker in via een Authentication klasse of via de UserMapper. Deze zal dan uit de DB de gegevens halen van de user en deze in de User klasse zetten. Uit de DB haal je op wat de rechten zijn van een user.
Je zou dan gewoon alleen een User klasse kunnen hebben. Doormiddel van de set...Strategy kun je dan alle rechten instellen aan de hand van de data uit de DB.

En een Guest. Tja, soms moet je verplicht zijn om ergens in gelogd te zijn maar wil je je niet registreren, dan is er soms een Guest optie. Dan zit je in het Guest object, deze Guest heeft vaak een naam (Guest124) en zal dus ook een eigen object krijgen die bijv. deze naam vast houdt.

Namespaces zijn niet heel moeilijk. Misschien dat mijn uitleg hier wel helpt: http://www.phphulp.nl/php/forum/topic/oop-gedachtengang/85017/5/#609868 (al vind ik het een moeilijk uit te leggen onderwerp)
euh, even inbreken.... wat wil je bereiken met de Permissions tabel?
Één User class lijkt me inderdaad handiger. Zeker omdat ik in de toekomst toe dit erg flexibel wil hebben. De beheerder van de applicatie moet de mogelijkheid hebben zelf te kiezen welke soort gebruikers er zijn. Neem nu als voorbeeld PHPhulp, dan kan je (bijvoorbeeld) volgende groepen onderscheiden: lid, moderator, redacteur, beheerder, ... . Neem je daarentegen bv. een portfolio dan zouden er bijvoorbeeld slechts twee groepen kunnen bestaan: klant en 'ik'. (In beide voorbeelden ga ik er vanuit dat een bezoeker [guest] geen rechten heeft.)

De enige vraag die mij dan rest...
Vroeger hield ik bv. de username, hash, ... bij (sessie) en keek ik op elke pagina na of de ingelogde recht heeft om de huidige pagina te bekijken. Indien ja: gebruiker kan alles doen wat er op die pagina mogelijk is. Indien nee: gebruiker krijgt melding dat hij onbevoegd is.

Aangezien de gegevens nu in een user object terecht komen, hoe geef je dit object dan door? Alles in een sessie gaan stoppen? (lijkt me niet dé oplossing) Of ga je op elke pagina na a.d.h.v. user_id is deze gebruiker gerechtigd (authenticatie)? Ja: maak user object; nee: niet gemachtigd (opnieuw inloggen / melding).

[size=xsmall]Toevoeging op 03/07/2012 14:32:21:[/size]

Jeroen vd op 03/07/2012 14:23:28

euh, even inbreken.... wat wil je bereiken met de Permissions tabel?

Bijhouden wat een gebruiker / groep al dan niet mag?
Je moet het security model aanhouden:

Eerst heb je de Authentication, je kijkt wie deze gebruiker is, of hij is ingelogd ect. Vervolgens doe je de Authorization die kijkt welke rechten je nodig hebt en welke rechten de Authentication heeft opgeleverd.
Wouter, het model begrijp ik. Maar ik zie niet direct in hoe je dan de implementatie gaat verwezenlijken? Wat ge je dan bijhouden in je sessie?

In mijn vroegere applicaties liet ik inderdaad inloggen en keek ik op de beveiligde pagina: is de gebruiker wel nog dezelfde (IP veranderd, geprutst met parameters, ...)

Ga je in dit geval bij de 'authorization' nagaan wat ik hierboven beschrijf en telkens opnieuw de permissies opnieuw uit de database halen, user-object maken (set...Strategy), ...? Om daarna dan te bepalen: aha, dit mag dit niet?
Je zou ook het User object kunnen serializen en dan in een session plaatsen bij Authentication kijken of de session bestaat, deze vervolgens unserializen en dan bij Authorization kijken of je de rechten hebt.

Bijhouden wat een gebruiker / groep al dan niet mag?

waarom in een aparte tabel? het lijkt mij dat een gebruiker maar 1 soort van controle heeft, hij kan geen admin en gast tegelijk zijn. zet in je usertabel een paar kolommen bij met de permisions, dit is namelijk uniek voor elke gebruiker, en nutteloos om daar dan een aparte tabel voor aan te maken (zie het als een wachtwoord - die zet je toch ook niet in een aparte tabel?)
@Jeroen

Daar ben ik het niet mee eens. Waarom zou je het niet splitsen? Dit verhoogt naar mijn mening de flexibiliteit. Stel morgen maak ik een applicatie die maar een paar permissie instellingen kent. Overmorgen maak ik een totaal andere applicatie met meer complexe permissies. De 'functie' gebruiker is in beide applicaties hetzelfde, de permissies niet.

Verder is er dan ook nog het indelen van groepen, dit is makkelijker met een aparte tabel voor permissies. Overigens heb je vaak de permissies niet nodig, gewoon zuiver gebruikersnaam en dergelijke. Dan is je query sneller afgehandeld, aangezien er minder werk is. Langs de andere kant, als je permissies nodig hebt, heb je een extra tabel nodig. Echter is het zo dat als je op de juiste wijze JOINS gebruikt dit erg efficiënt werkt.

@Wouter
Lijkt me een goed plan. Volgens mij is het dan het handigste om in de User class een serialize en deserialize functie te voorzien? Of eventueel eerst in een interface stoppen, zodanig dat andere objecten op dezelfde manier geserialiseerd kunnen worden.

Reageren