Skaptrollet Skrevet 14. oktober 2008 Del Skrevet 14. oktober 2008 (endret) Hei, jeg utvikler et rammeverk for egen nytte, men har nå kommet til et lite problem med hvordan jeg skal begrense tilgangen til forskjellige sider / funksjoner etter tilgangsnivå til brukeren. Rammeverket er MVC basert så alle sider er definert med klasse/metode i uri. Har alltid brukt tallbasert tilgangsnivåer, hvor f.eks side x krever at man har et tilgangsnivå > 3 f.eks, men tenkte jeg skulle utvide dette litt. Tanken nå er at jeg kan lage en tabell i databasen hvor klasse (controller) og metode er definert, og en bruker id. noe sånt: | klasse | metode | brukerid | news | add | 1 | news | edit | 1 Tenkte også å bare kalle opp en statisk klasse som inneholder alt som har med brukerinformasjon å gjøre i hver metode, f.eks: User::check(); Denne statiske metoden sjekker så om brukeren er logget inn, og så sjekker om klassen og metoden som kalte denne sjekken og brukeren finnes i denne tilgangstabellen i en rad (alle felter som primærnøkler), og så enten, finner brukeren og gjør ingenting (logger bevegelsene kanskje), eller redirecter brukeren til en side som viser at den ikke har tilgang og stopper parsing av den siden. Eneste måten jeg kan tenke meg å gjennomføre dette på er å kjøre en debug_backtrace og hente ut klasse og funksjon som kalte den sjekken fra denne backtracen for å finne metodenavn og klassenavn, UTEN å måtte sende det med det User::check(__CLASS__, __FUNCTION__) hver eneste gang. Men jeg har på følelsen at det med debug_backtrace er en veldig stygg måte å løse det på...? Noen innvendinger? Kanskje en annen måte å få så detaljert oversikt over hver brukers tilgangsnivåer? Forslag til andre måter å gjøre det med tanke på databasen hvis jeg også skulle hatt med grupper med forskjellige tilgangsnivåer også? Hatt en helt lik tabell som referer til grupper og prioritere brukerrettigheter over grupperettigheter dersom det er konflikt? Hadde satt pris på deres syn på saken. Takk for svar! Mvh, WaBBiT Endret 14. oktober 2008 av WaBBiT Lenke til kommentar
Jonas Skrevet 14. oktober 2008 Del Skrevet 14. oktober 2008 Siden du bruker MVC, så antar jeg du har en autoload-funksjon som includer() klassene og hvor klassen initialiseres etterpå. Da har du jo navnet på klassen og kan sjekke tilgangsnivå. Tror ideen om en statisk funksjon som sjekker hvor den er kalt fra via backtrace er en dårlig idé. Det er ikke det funksjonen er ment til. Lenke til kommentar
Skaptrollet Skrevet 14. oktober 2008 Forfatter Del Skrevet 14. oktober 2008 Kunne selvsagt lagt denne sjekken i pagecontroller som kaller hver controller og metode, men tanken er at denne tilgangskontrollen skal være en ekstern modul, og kunne enkelt byttes ut... derfor vil jeg ikke legge denne sjekken dit, fordi denne pagecontrolleren er en del av kjernen i rammeverket... Blir litt dumt å ha if(module('something')) overalt.. bedre å la brukeren (meg) velge hvordan det skal bygges opp... En kanskje bedre ide er å sette hvilken klasse og hvilken metode som er den som blir brukt i pagecontroller og la denne auth metoden hente det ut derfra? Det er den beste måten tror jeg.. Setter da $_current_controller og $_current_method i autload/pagecontroller og sjekker de, men mister litt fleksibilitet, hvis jeg f.eks vil sikre meg mot eventuelle sikkerhetshull, eller paranoid sikkerhet ved å kunne styre hvilke models en bruker også skal ha tilgang til og egentlig alt, hvis jeg hadde brukt debug_backtrace... da vil det fort bli umulig å bruke metoder som ikke brukeren har lov til...? Kan aldri være for sikker på at en eller annen ondsinnet bruker klarer å få kjørt en metode som f.eks endrer en kritisk fil.... om den brukeren bruker sitt eget script og kjører metoden via include() fordi vi deler samme server ellerno... debug_backtrace gav ikke noe merkbar forskjell i ytelse heller... Tror jeg går for å sette current controller og current method og hente det ut derfra, hvis ingen andre har noen bedre forslag? Lenke til kommentar
Jonas Skrevet 14. oktober 2008 Del Skrevet 14. oktober 2008 (endret) Tror ikke du helt forstod hva jeg mente. Jeg mente absolutt ikke at du skulle putte en haug med identiske koder overalt. Tenkte noe i denne retningen. (Controller) <?php // Include the class, which is the most upper level of the MVC-model require_once ( WORKING_DIRECTORY . '/modules/' . $module . '/' . $class . '.php' ); // Create an instance // This will add MVC-layers through inheritance if ( auth ( $class ) ) $instance = new $class (); ?> Vil uansett påstå at det en dårlig metode. Selv lar jeg alle klassene mine arve fra et sett med autentiseringsklasser, som hver sjekker brukerens tilgangsnivå. <?php class AdminToggleTicket extends PartyAdmin { // 1 .. 2 .. 3 } ?> <?php class PartyAdmin extends Etc.. { public function auth () { return $user['level'] >= 2; } } ?> Endret 14. oktober 2008 av Jonas Lenke til kommentar
Harald B Skrevet 15. oktober 2008 Del Skrevet 15. oktober 2008 Hva med å bruke en decorator slik: class AuthDecorator { private $_class; private $_valid_methods = array(); private $_db; public function __construct($class) { $this->_class = $class; $this->_db = DAO::getInstance(); // query to populate $this->_valid_methods if (!$this->_db->numRows()) { // no access to class throw new AccessViolationException; } } public function __call($method, $arguments) { if ( in_array($method, (array) $this->_valid_methods) ) { return call_user_func_array(array($this->_class, $method), (array) $arguments); }else{ // no access to method throw new AccessViolationException; } } } Da kan du bruke denne på klassene som skal være gjenstand for tilgangskontroll uten at klassen selv trenger å implementere noe som helst slik: $class = new ClassName(); $class = new AuthDecorator($class); Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå