Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [ZendFramework] uwierzytelnianie z dodatkowym parametrem, Zend_auth
czachor
post 28.04.2009, 22:05:01
Post #1





Grupa: Zarejestrowani
Postów: 897
Pomógł: 40
Dołączył: 16.12.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Witam,

kombinuję dzisiaj z Zend_Auth i coś mi nie idzie... Chciałbym, żeby oprócz standardowego sprawdzania nazwy i hasła w bazie spełniony był również warunek 'active = TRUE'.
Mam kod z manuala, ale nie działa, logują się nieaktywowani użytkownicy...

Niżej mój kod. Wszystko jest ok, tylko zupełnie ignorowany jest warunek... Będę wdzięczny za pomoc.
  1. <?php
  2. class LoginController extends Main_Controller_Action
  3. {
  4.    function indexAction()
  5.    {
  6.        if ($this->_request->isPost())
  7.        {
  8.            $f = new Zend_Filter_HtmlEntities(ENT_QUOTES);
  9.            $username = $f->filter($this->_request->getPost('user'));
  10.            $password = sha1($f->filter($this->_request->getPost('upasid')));
  11.  
  12.            if (empty($username))
  13.            {
  14.                $this->view->message = 'Nie podano nazwy użytkownika.';
  15.            }
  16.            else
  17.            {
  18.                $db = Zend_Registry::get('db');
  19.                $authAdapter = new Zend_Auth_Adapter_DbTable($db,
  20.                    'users',
  21.                    'name',
  22.                    'password',
  23.                    ' AND active = TRUE');
  24.  
  25.                //$authAdapter->setTableName('users');
  26.                //$authAdapter->setIdentityColumn('name');
  27.                //$authAdapter->setCredentialColumn('password');
  28.                $authAdapter->setIdentity($username);
  29.                $authAdapter->setCredential($password);
  30.  
  31.                $auth = Zend_Auth::getInstance();
  32.                $result = $auth->authenticate($authAdapter);
  33.  
  34.                switch ($result->getCode())
  35.                {
  36.                    case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
  37.                        //nieistniejący użytkownik
  38.                        $this->view->message = 'Użytkownik o podanym loginie nie istnieje.';
  39.                    break;
  40.  
  41.                    case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
  42.                        //niepoprawne hasło
  43.                        $this->view->message = 'Nieprawidłowe hasło.';
  44.                    break;
  45.  
  46.                    case Zend_Auth_Result::SUCCESS:
  47.                        //sukces
  48.                        if ($result->isValid())
  49.                        {
  50.                            $data = $authAdapter->getResultRowObject(null, 'password');
  51.                            $auth->getStorage()->write($data);
  52.                            $this->_redirect('somewhere');
  53.                        };
  54.                    break;
  55.  
  56.                    default:
  57.                        //to do
  58.                    break;
  59.                };
  60.            };
  61.        };
  62.    }
  63. }
  64. ?>


--------------------
how many SEO experts does it take to change a light bulb,lightbulb,light,bulb,lamp,lighting,switch,sex,xxx
5-Reasons-why-you-should-NEVER-fix-a-computer-for-free
Go to the top of the page
+Quote Post
batman
post 29.04.2009, 07:11:49
Post #2





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




Nie do końca zrobiłeś jak w manualu.
Nie widzę sprawdzenia hasła (MD5(?)) - chyba, że nie masz haseł zapisanych w md5. Poza tym TRUE powinno być w cudzysłowie - "TRUE". No i na koniec nie jestem pewien, czy powinien być ten pierwszy AND.


--------------------
I would love to change the world, but they won't give me the source code.
My software never has bugs. It just develops random features.
Go to the top of the page
+Quote Post
gazelek
post 29.04.2009, 12:09:54
Post #3





Grupa: Zarejestrowani
Postów: 85
Pomógł: 3
Dołączył: 28.02.2008

Ostrzeżenie: (0%)
-----


Pozwole sie podpiac. Wykorzystuje powyzszy przyklad z manuala. Chcialem zrobic dwa logowania w obrebie jednej strony (jedno dla uzytkownika, drugie dla administratora). Wykorzystujac ten przyklad uzytkownik po zalogowaniu sie uzyskuje dostep rowniez do panelu administracyjnego. Czy jest jakas metoda rozwiazania tego po stronie skryptu? Bo jedyne, co mi przychodzi teraz na mysl, to usuniecie tabeli administratorow i nadawanie uzytkownikom praw dostepu, ale to rozwiazanie po stronie bazy danych....
Go to the top of the page
+Quote Post
czachor
post 29.04.2009, 12:11:57
Post #4





Grupa: Zarejestrowani
Postów: 897
Pomógł: 40
Dołączył: 16.12.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Racja, jest trochę inaczej. Nie zrobiłem sprawdzania hasła, bo używam sha1, a baza to postgres (błąd, nie napisałem od razu). Pogrzebałem trochę w kodzie Zend_Auth i doszedłem do tego, że musi tam być znak zapytania. Po kilku próbach w PostgreSQL'u zadziałała taka konstrukcja (trochę zmieniona do powyższej, ale de facto jest to to samo):
  1. <?php
  2. $authAdapter = new Zend_Auth_Adapter_DbTable($db);
  3. $authAdapter->setTableName('users');
  4. $authAdapter->setIdentityColumn('name');
  5. $authAdapter->setCredentialColumn('password');
  6. $authAdapter->setCredentialTreatment('? AND active = TRUE');
  7. $authAdapter->setIdentity($username);
  8. $authAdapter->setCredential($password);
  9. ?>

Moje spostrzeżenie: w postgresie nie działa konstrukcja podana w dokumentacji ZF (chodzi o cudzysłowia):
  1. <?php
  2. $authAdapter->setCredentialTreatment('? AND active = "TRUE"');
  3. ?>

Nie ma również wbudowanej funkcji SHA1, więc robię to na poziomie php. Gdyby ktoś chciał, można ją sobie dorzucić do bazy:
  1. CREATE OR REPLACE FUNCTION sha1(bytea) returns text AS $$
  2. SELECT encode(digest($1, 'sha1'), 'hex')
  3. $$ LANGUAGE SQL STRICT IMMUTABLE;

a potem:
  1. <?php
  2. $authAdapter->setCredentialTreatment('SHA1(?) AND active = TRUE');
  3. ?>


--------------------
how many SEO experts does it take to change a light bulb,lightbulb,light,bulb,lamp,lighting,switch,sex,xxx
5-Reasons-why-you-should-NEVER-fix-a-computer-for-free
Go to the top of the page
+Quote Post
batman
post 29.04.2009, 13:14:47
Post #5





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




Cytat(gazelek @ 29.04.2009, 13:09:54 ) *
Chcialem zrobic dwa logowania w obrebie jednej strony (jedno dla uzytkownika, drugie dla administratora).

Logowanie robisz jedno. Musisz odpowiednio nadać prawa dostępu. Poczytaj o Zend_Acl.

~czachor
O ile się nie myle to w pg w kolumnach typu bool jest t i f zapisane. Z tego właśnie powodu wszystkie wartości true/false zapisuję jako smallint/tinyint. O wiele łatwiej przesiąść się na inną bazę danych.
Jeśli nie podasz znaku zapytania, zostanie on dopisany automatycznie.


--------------------
I would love to change the world, but they won't give me the source code.
My software never has bugs. It just develops random features.
Go to the top of the page
+Quote Post
czachor
post 29.04.2009, 19:38:27
Post #6





Grupa: Zarejestrowani
Postów: 897
Pomógł: 40
Dołączył: 16.12.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Fakt, znak zapytania dopisał się sam.
Co do pg bool:
Cytat(manual pg)
boolean can have one of only two states: "true" or "false".
Valid literal values for the "true" state are:

TRUE
't'
'true'
'y'
'yes'
'1'

For the "false" state, the following values can be used:

FALSE
'f'
'false'
'n'
'no'
'0'

Wiem, że kiedyś był z tym problem, ale od którejś wersji pg zniknął. W eksporcie też mam true/false, więc może zależy teraz to od tego, co się w to pole wstawiło.


--------------------
how many SEO experts does it take to change a light bulb,lightbulb,light,bulb,lamp,lighting,switch,sex,xxx
5-Reasons-why-you-should-NEVER-fix-a-computer-for-free
Go to the top of the page
+Quote Post
gazelek
post 22.05.2009, 14:10:05
Post #7





Grupa: Zarejestrowani
Postów: 85
Pomógł: 3
Dołączył: 28.02.2008

Ostrzeżenie: (0%)
-----


Cytat(batman @ 29.04.2009, 14:14:47 ) *
Logowanie robisz jedno. Musisz odpowiednio nadać prawa dostępu. Poczytaj o Zend_Acl.


Jakos nie bylo czasu sie tym zajac, az do dzisiaj. Przeczytalem sekcje manuala dotyczaca Zend_Acl. Pogooglowalem troche, ale ciagle nie moge znalezc zwiazku miedzy Zend_Auth (za pomoca ktorego przeprowadzam logowanie) a wlasnie Zend_Acl. Na chlopski rozum - po zalogowaniu trzeba w jakis sposob ustawic rolę uzytkownika, ktory sie wlasnie zalogowal. Dobrze mysle? Bo skoro mam zdefiniowane:

Kod
$this->addRole(new Zend_Acl_Role('domyslna'));
$this->addRole(new Zend_Acl_Role('uzytkownik'),'domyslna');
$this->addRole(new Zend_Acl_Role('admin'), 'uzytkownik');

//ciach ciach, ponizej ustawienia resursow dla powyzszych rol


to w jaki sposob po logowaniu ustawic, jaka role pelni ten ktos, kto sie zalogowal?
Go to the top of the page
+Quote Post
batman
post 22.05.2009, 14:17:49
Post #8





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




W tabeli użytkowników przechowujesz informację do jakiej roli należy użytkownik (przyjmijmy dla uproszczenia, że użytkownik może być przypisany tylko do jednej roli). Podczas logowania sprawdzasz do jakiej roli jest przypisany, a następnie sprawdzasz, czy rola ma dostęp do aktualnego zasobu (isAllowed). W ten oto prosty sposób masz rozwiązaną autentykację oraz autoryzację.
Sprawdzanie praw dostępu najlepiej zrobić w pluginie, by nie duplikować kodu.


--------------------
I would love to change the world, but they won't give me the source code.
My software never has bugs. It just develops random features.
Go to the top of the page
+Quote Post
gazelek
post 22.05.2009, 15:34:29
Post #9





Grupa: Zarejestrowani
Postów: 85
Pomógł: 3
Dołączył: 28.02.2008

Ostrzeżenie: (0%)
-----


Sprawdzanie, o ktorym piszesz mialoby miejsce przy logowaniu. A jak rozwiazac ta kwestie na innych podstronach? Zakladam, ze user loguje sie na stronie glownej, a pozniej wklepuje w pasek adresu mojastrona.com/admin - czy dostep zostanie mu zablokowany z automatu, czy musze dodatkowo sprawdzac, czy ma uprawnienia? Bo zakladam, ze pelniona przez usera role zapisalbym np w sesji i pozniej to sprawdzal... no chyba, ze to sie robi jakos z automatu przy uzyciu Zend_Acl - nie chce dublowac kodu niepotrzebnie. Bo w sumie napisanie wlasnej klasy dziedziczacej z Zend_Acl, poszerzona o sprawdzanie autentykacji to nie jest problem....

Edit: dzieki za pomoc, juz sobie poradzilem, znalazlem przykladowy kod, ktory mi wszystko rozjasnil winksmiley.jpg

Ten post edytował gazelek 22.05.2009, 16:12:17
Go to the top of the page
+Quote Post
pgrzelka
post 22.05.2009, 16:23:05
Post #10





Grupa: Zarejestrowani
Postów: 313
Pomógł: 24
Dołączył: 9.08.2008
Skąd: Kielce

Ostrzeżenie: (0%)
-----


kiedyś w jednym skrypcie zrobiłem coś takiego, może Ci pomoże ten kod
w pluginie tworzysz funkcję preDispatch, w niej pobierasz uprawnienia usera z bazy, tworzysz tablicę z tych uprawnień,
następnie sprawdzasz czy wywołany controller znajduje się w tablicy, jeśli nie to obsługujesz błąd.
kod nie jest doskonały, ale działa smile.gif
Kod
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $m = $request->getModuleName();
        $c = $request->getControllerName();
           $session = Zend_Registry::get('session');

        $acc = $session->acc; // to jest wiersz pobrany z bazy danych przy logowani, a następnie zapisany w sesji,  kolejne kolumny a1,a2.. mają wartość 0 lub 1

        $allow = array();
        if ($acc['a1']) $allow[] = 'news';  // news to controller do którego albo ma dostęp albo nie ma dostępu
        if ($acc['a2']) $allow[] = 'polls';
        if ($acc['a3']) $allow[] = 'pages';
        if ($acc['a4']) $allow[] = 'album';
        if ($acc['a5']) $allow[] = 'regards';
        if ($acc['a6']) $allow[] = 'comments';
        
        if (!in_array($c,$allow))
        {
            $request->setControllerName('error');
            $request->setActionname('error');
            throw new Exception('', 403);    
        }
     }


Ten post edytował pgrzelka 22.05.2009, 16:24:36


--------------------
Go to the top of the page
+Quote Post
gazelek
post 22.05.2009, 22:29:46
Post #11





Grupa: Zarejestrowani
Postów: 85
Pomógł: 3
Dołączył: 28.02.2008

Ostrzeżenie: (0%)
-----


Pozwole sobie jeszcze poprosic o pomoc... ustawilem sobie juz wszystko (Zend_Registry, reguly do Zend_Acl, sesje), napisalem plugin (kod macie ponizej). Problem polega na tym, ze wszystkie parametry zmiennej $request (konkretnie te, ktore mnie interesuja: module, controller i action) maja wartosc NULL. Niezaleznie od tego, czy uzyje zmiennej z linijki 16 czy z 17... wlasciwie juz wszystko by mi mialo dzialac, poza tym zakichanym $request...
Dodam, ze var_dump($request) wykonany w ktorymkolwiek kontrollerze zwraca poprawny wynik...

Obiekt typu Jpg_Acl tworzony jest w pliku Initializer.php, wtedy tez przekazywany jest do niego $request, wiec moze wtedy nie ma tam przypisanych jeszcze modułu, kontrollera i akcji... Jak w takim razie to rozwiazac? Bo troche mi sie pomysly skonczyly, a jestem juz dosc blisko celu tongue.gif

Kod
<?php
    
    class Jpg_Acl extends Zend_Controller_Plugin_Abstract{
        
        protected $_acl;
        
        protected $_role;

        public function __construct($request,$acl,$rola='guest'){
            $this->_acl = $acl;
            $this->_role = $rola;
            $this->check($request);
        }
        
        public function check(Zend_Controller_Request_Abstract $request){
            var_dump($this->getRequest());
            //var_dump($request); zwraca taki sam wynik jak wyzej....
            $resourceName = $this->_request->getModuleName();
            if (!$this->_acl->isAllowed($this->_role, $resourceName, $request->getActionName())) {
                //$this->denyAccess($request);
            }
        }
        
        private function denyAccess(Zend_Controller_Request_Abstract $request){
            echo '<script language="javascript">location.replace("'.$request->getBaseUrl().'");</script>';
        }
    }
?>


Ten post edytował gazelek 22.05.2009, 22:31:36
Go to the top of the page
+Quote Post
pgrzelka
post 23.05.2009, 01:41:37
Post #12





Grupa: Zarejestrowani
Postów: 313
Pomógł: 24
Dołączył: 9.08.2008
Skąd: Kielce

Ostrzeżenie: (0%)
-----


request ma jakąś wartość czy jest NULL ?

zrób w tym pluginie funkcję preDispatch($request) zamiast check();
w odpowiednim momencie zostanie ona wywołana przez frameworka, a zmienna $request będzie miała poprawne wartości, nie wywołuj sam tej funkcji.


--------------------
Go to the top of the page
+Quote Post
gazelek
post 23.05.2009, 14:53:10
Post #13





Grupa: Zarejestrowani
Postów: 85
Pomógł: 3
Dołączył: 28.02.2008

Ostrzeżenie: (0%)
-----


request ma wartosc, ale te trzy zmienne (module,controller i action) sa NULL. Po zmianie nazwy funkcji na preDispatch i dodaniu testowego napisu (echo "test";) on sie wogole nie wyswietla -> funkcja sie nie wykonuje...
Struktura katalogu library:
library/
Zend/
tutaj biblioteki Zenda
Jpg/
MyAcl.php

Pytanie - czy nie musze zrobic czegos na wzor pluginow Zenda? W sensie tak:
library/
Jpg/
Acl/
tu jakies pliki, w ktoryms z plikow tego katalogu funkcja preDispatch
MyAcl.php

Czy to ma jakies znaczenie? Bo mam akurat taki przykladowy kod zrodlowy (niestety, podzial tylko na dwie role) i tam to jest wlasnie tak rozwiazane.
Go to the top of the page
+Quote Post
pgrzelka
post 23.05.2009, 15:31:01
Post #14





Grupa: Zarejestrowani
Postów: 313
Pomógł: 24
Dołączył: 9.08.2008
Skąd: Kielce

Ostrzeżenie: (0%)
-----


a jak tworzysz ten plugin?
new Jpg_Acl(zmienne);
czy
$frontcontroller -> registerPlugin(new Jpg_Acl(zmienne));

przeczytaj sobie to
http://framework.zend.com/manual/en/zend.c...er.plugins.html

Ten post edytował pgrzelka 23.05.2009, 15:33:06


--------------------
Go to the top of the page
+Quote Post
gazelek
post 23.05.2009, 22:48:11
Post #15





Grupa: Zarejestrowani
Postów: 85
Pomógł: 3
Dołączył: 28.02.2008

Ostrzeżenie: (0%)
-----


Brawo, o to wlasnie chodzilo. Wielkie dzieki, nie moge kliknac 'Pomogl' bo go nie ma, ale wysylam raport do moderatora, zeby Ci punkcik dodal! winksmiley.jpg
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 24.06.2025 - 03:56