Doctrine 2 Entita jako potomek \Nette\Security\User

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
hapi
Člen | 35
+
0
-

Dobrý večer,
v Nette 2.0.5 používám Doctrine 2. Myslíte že má smysl aby entita User byla zároveň potomkem třídy \Nette\Security\User. Očekával bych, že v Pressenteru po zavolání $this->getUser() dostanu konkrétního uživatele, tedy entitu. Nikde jsem to ale takto implementováno nenašel a nejsem si jistý, zdali to má nějaký důvod.

Problém je, co vrátí metoda getUser(), pokud není uživatel přihlášen. Jestli je dobrý nápad vracet novou entitu.

Předem děkuji za odpovědi :)

sodae
Nette Evangelist | 250
+
+1
-

Co potřebuješ je Identity, kterou získáš z $this->getUser()->getIdentity() v presenteru. Při authentizaci vrátíš entitu implementující interface Nette\Security\IIdentity.
Třída Nette\Security\User je určena ke správě uživatele. Zatímco Identity je místo na informace o přihlášeném uživateli.

hapi
Člen | 35
+
0
-

Díky za rychlou odpověď, ale moc nerozumím proč zrovna entitu Identity držet v databázi. Tedy né že by se to nijak nehodilo, ale logičtější mi přijde mít jako entitu uživatele, už jen ty metody, které má Nette\Security\User, v DB můžu držet i indormaci o tom, zdali je User přihlášen atp. Uživatel se přihlašuje, odhlašuje, nese informace o sobě jako e-mail, heslo, kontaktní údaje.

Hlavně v mém systému, který je zároveň prvním projektem, co v Nette dělám, bude moci mít uživatel několik uživatelských účtů. Přihlašuji ale uživatele, a je v podstatě jedno pod jakým účtem…

Editoval hapi (16. 9. 2012 21:48)

bazo
Člen | 620
+
0
-

takto:

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
 * Description of User
 *
 * @author Martin
 * @ODM\Document
 *
 */
class User implements Nette\Security\IIdentity
{
	private
		/**
		 * @ODM\Id
		 */
		$id,

		/**
		 * @ODM\String
		 * @ODM\Index(unique=true)
		 */
		$email,

		/**
		 * @ODM\String
		 */
		$password,

		/**
		 * @ODM\Boolean
		 */
		$active = false,

		/**
		 * @ODM\Date
		 * @ODM\Index(order="desc")
		 */
		$registered
	;

	public function __construct()
	{
		$this->registered = new DateTime;
	}

	public function getId()
	{
		return $this->id;
	}

	public function getRoles()
	{
		return array(
			'user'
		);
	}
}

a

$this->getUser()->getIdentity()

ti vrati entitu User

hapi
Člen | 35
+
0
-

Ale jo, ja nemam problem s implementaci, spis me zajima proc teda ma byt entita User identita a ne User :) uz jen to, ze getUser() vrati User, a getIdentity() vrati User, pokazde to je jina trida, ale v podstate je to to samy :)

Neresim tedy jak to naprogramovat, ale proc to tak naprogramovat :) Sice bych Vam mohl verit a slepe to udelat, ale budu porad stejne hloupej :D

Patrik Votoček
Člen | 2221
+
0
-

User (jakože Nette\Security\User je vice méně služba která se stará o „správu“ Identity (jakože Nette\Security\IIdentity.

Identita reprezentuje identitu přihlášeného uživatele. Kdežto user se zjednodušeně stará o jeho přihlášení, ověření zda byl přihlášen, jestli má potřebná oprávnění atd.

hapi
Člen | 35
+
0
-

Včera jsem nad tím ještě přemýšlel, a ani sám moc nevím co mi na tom nejde přes prsty, spíš asi to zmatené pojmenování které mi tam vznikne. Někdo přijde k mým zdrojákům, ke všemu nebude znát nette a bude se divit, proč getUser nevrací uživatele jako takového, a mnusí teprve vytáhnout identitu, kterou je už onen uživatel.

Možná kdyby služba byla dejme tomu Auth a místo getIdentity bylo getUser :) Ale to už je věc názoru :)

Jinak co psal Patrik Votoček taky v podstatě chápu. Teď je ještě otázka, jestli je vhodné aby uživatel (entita) byl identitou (potomkem). Každý přeci máme identitu, ale sami o sobě asi identity nejsme.

Jestli ve finále není lepší to nechat tak jak je. Do identity si opravdu nacpat ty data, která běžně potřebuji. A samotného usera (entitu) si loadnout „ručne“, až když je potřeba.

Takže by mě zajímalo kolik z Vás má Nette\Security\IIdentity uloženou v DB.

Z mého pohledu, pokud už v tom FW je User a Identity, tak to má z pohledu autora nějaký význam, a vytvářet z Identity Usera mi přijde jako obcházení toho návrhu. Něco ve stylu: „Jak to tam co nejjednodušeji nacpat? Aha, udělam z Identity kočkopsa a podědím ji.“

Editoval hapi (17. 9. 2012 8:27)

arron
Člen | 464
+
0
-

Já chápu Nette\Security\User jako „systémového usera“. Tzn. objekt, který spravuje usera z hlediska frameworku. Tenhle user má nějakou identitu (id, name, role), má nějaká práva a umí si je ověřovat, když je to potřeba.

User, kterého ukládáme do databáze je v podstatě „aplikační user“. Je to uživatel, se kterým umí pracovat aplikace, ví, jaký význam tenhle uživatel má, umí ho ukládat, přiřazovat mu práva a podobně. A mimo jiné ho umí „převést“ na systémového uživatele pomocí procesu autentikace.

Ten probíhá tak, že si aplikace nějakým svým způsobem z databáze dostane uživatele, nějak ho ověří a pak frameworku dodá potřebné informace (identitu) o uživateli, čímž ho převede na "systémového usera.

Takže Ty opravdu ukládáš v podstatě identitu uživatele, ale ukládáš si k němu i další informace, se kterými umí pracovat Tvoje aplikace (například heslo…). Systémovou identitu pak vytvoříš při autentizaci.

Možná je to trochu kostrbaté přirovnání, ale třeba Ti to pomůže :-)

hapi
Člen | 35
+
0
-

To je to co jsem potřeboval vědět :) Tedy né že by mě to nenapadlo, ale spíš jsem potřeboval slyšet názor někoho, kdo už má nějakou zkušenost. Nechci z důvodu počáteční neznalosti rozkopat návrh, který už je prověřený.

Z toho co zde arron napsal bych se přikláněl k tomu že i identitu a uživatele (entitu) bych nechal odděleně a identitu spíš chápal jako jakýsi „token“ nebo jak to nazvat…

Ona bohužel dokumentace je podle mne nejslabší článek Nette. Takže jsem rád za každou odpověď :)

Editoval hapi (17. 9. 2012 10:32)

bazo
Člen | 620
+
0
-

hapi napsal(a):

Včera jsem nad tím ještě přemýšlel, a ani sám moc nevím co mi na tom nejde přes prsty, spíš asi to zmatené pojmenování které mi tam vznikne. Někdo přijde k mým zdrojákům, ke všemu nebude znát nette a bude se divit, proč getUser nevrací uživatele jako takového, a mnusí teprve vytáhnout identitu, kterou je už onen uživatel.

Možná kdyby služba byla dejme tomu Auth a místo getIdentity bylo getUser :) Ale to už je věc názoru :)

Jinak co psal Patrik Votoček taky v podstatě chápu. Teď je ještě otázka, jestli je vhodné aby uživatel (entita) byl identitou (potomkem). Každý přeci máme identitu, ale sami o sobě asi identity nejsme.

Jestli ve finále není lepší to nechat tak jak je. Do identity si opravdu nacpat ty data, která běžně potřebuji. A samotného usera (entitu) si loadnout „ručne“, až když je potřeba.

Takže by mě zajímalo kolik z Vás má Nette\Security\IIdentity uloženou v DB.

Z mého pohledu, pokud už v tom FW je User a Identity, tak to má z pohledu autora nějaký význam, a vytvářet z Identity Usera mi přijde jako obcházení toho návrhu. Něco ve stylu: „Jak to tam co nejjednodušeji nacpat? Aha, udělam z Identity kočkopsa a podědím ji.“

identita sa nededi, ale implementuje. metodu getId() by aj tak mala mat kazda entita. entitu Usera si pri authentikacii tak ci tak musis vytiahnut z db, tak uz mas jedno ci ju vratis rovno ako Identity alebo si odtial povytahujes co potrebujes.

ja aj tak v startupe basePresentera este raz vytahujem aktualnu User entitu, lebo ta v identite je detachovana

hapi
Člen | 35
+
0
-

bazo napsal(a):
identita sa nededi, ale implementuje. metodu getId() by aj tak mala mat kazda entita. entitu Usera si pri authentikacii tak ci tak musis vytiahnut z db, tak uz mas jedno ci ju vratis rovno ako Identity alebo si odtial povytahujes co potrebujes.

ja aj tak v startupe basePresentera este raz vytahujem aktualnu User entitu, lebo ta v identite je detachovana

bazo napsal(a):
identita sa nededi, ale implementuje.

Jasne, to vim, jen jsem se do toho trosku zamotal. User nema rozhrani, Identita ano :)

bazo napsal(a):
entitu Usera si pri authentikacii tak ci tak musis vytiahnut z db, tak uz mas jedno ci ju vratis rovno ako Identity alebo si odtial povytahujes co potrebujes.

No a ted prave premyslim co je lepsi. Jestli je lepsi mit entitu User jako onu identitu implementaci rozhrani a primo ji v authenticatoru vracet a nebo jak rikas si jen vytahat data a mit tedy Identity oddelene od entity User.

bazo napsal(a):
ja aj tak v startupe basePresentera este raz vytahujem aktualnu User entitu, lebo ta v identite je detachovana

Zde bych prave videl vyhodu reseni, kdy $this->getUser()->getIdentity() vraci primo entitu User, ze uz se nemusim znovu starat o jeji nacteni.
Nadruhou stranu mi to neprijde koser uz jen z duvodu toho pojmenovani. Porad si myslim ze by neco jako $this->auth()->getUser() bylo hezci :)

Patrik Votoček
Člen | 2221
+
0
-

hapi napsal(a):

Jinak co psal Patrik Votoček taky v podstatě chápu. Teď je ještě otázka, jestli je vhodné aby uživatel (entita) byl identitou (potomkem). Každý přeci máme identitu, ale sami o sobě asi identity nejsme.

Představ si identitu jako takovou občanku resp. spíš řidičák (máš tam jednoznačnou identifikaci a taky tam máš co můžeš řídit ). A User je takovej policajt kterej je schopen si ze tvé peněřenky ten řidičák vytáhnout (načíst ze session) a ověřit jesli řídíš to co můžeš (ověření oprávnění) , na dopravce ti ho zase vydají (přihlášení).

Na 99% míst nikoho nezajímáš ty jako osoba. Ale nějaká tvá jednoznačná identifikace (občanka, pas nebo řidičák).

Pokud potřebuješ jakékoli další údaje nic ti nebrání je mít součástí Identity případně v další entitě na kterou uděláš asociaci (sám to tak používám).

hapi
Člen | 35
+
0
-

Jo, to je logicke. Ted uz jsem ve fazi kdy neresim, jak to udelam.
Ale to pojmenovani je z meho pohledu nestatsne, protoze ve finale budu mit v kodu volani $this->getUser()->getIdentity()->getUser() :D nebylo by teda lepsi neco jako $this->PoliceOfficer()->getUserIdentity()->getIdentityOwner()->moveUserToJail() :D

bazo
Člen | 620
+
0
-

hapi napsal(a):

bazo napsal(a):
ja aj tak v startupe basePresentera este raz vytahujem aktualnu User entitu, lebo ta v identite je detachovana

Zde bych prave videl vyhodu reseni, kdy $this->getUser()->getIdentity() vraci primo entitu User, ze uz se nemusim znovu starat o jeji nacteni.
Nadruhou stranu mi to neprijde koser uz jen z duvodu toho pojmenovani. Porad si myslim ze by neco jako $this->auth()->getUser() bylo hezci :)

no len ked si user nieco zmeni tak v identite budu stale stare data

Patrik Votoček
Člen | 2221
+
0
-

hapi napsal(a):

Ale to pojmenovani je z meho pohledu nestatsne, protoze ve finale budu mit v kodu volani $this->getUser()->getIdentity()->getUser() :D

To z toho ale děláš ty. :-) Co vrátí getIdentity()->getUser()? Nějáký profil uživatele (proč se to nejmenuje profil)? Něco jiného? Není pro to lepší název?

hapi
Člen | 35
+
0
-

Patrik Votoček napsal(a):

hapi napsal(a):

Ale to pojmenovani je z meho pohledu nestatsne, protoze ve finale budu mit v kodu volani $this->getUser()->getIdentity()->getUser() :D

To z toho ale děláš ty. :-) Co vrátí getIdentity()->getUser()? Nějáký profil uživatele (proč se to nejmenuje profil)? Něco jiného? Není pro to lepší název?

Tak jako jiny nazev me napada jedine Person, profil mi neprijde uplne vhodne pojmenovani, jelikoz kolem osoby ci uzivatele. Samozrejme prejmenovat se to da snadno, jeste na to neni nic napojeno, aby se jednalo o slozity refaktoring. Uzivatel ma svoji identitu, ale je spravne ze identita ma osobu? Nema snad osoba svoji identitu. Obcanka taky beze me bude tezko existovat. Proto mi prislo logictejsi mi nejakou autorizacni sluzbu, ktera bude mit k dispozici prihlaseneho uzivatele. Zde nejde o spatny navrh, spis zmatene pojmenovani.

Tedy potom je jedine podle me mozne logicke reseni ze Nette\Security\User ma instanci objektu Person implementujici rozhrani Identity.

Protoze nema smysl aby mel Uzivatel Identitu majici svoji osobu.

To uz by mohlo byt ne?

Patrik Votoček
Člen | 2221
+
0
-

Znovu se ptám Co to je Person/User? Předpokládám že člověka nebereš a neukládáš do DB :-) . Proto mě to celé připadá zmatené. Ty potřebuješ jednoznačnou identifikaci člověka tedy jeho Identitu. Ale asi těžko budeš používat člověka (ten přece sedí za počítačem a ovládá aplikaci).

Elijen
Člen | 171
+
0
-

Ale to pojmenovani je z meho pohledu nestatsne, protoze ve finale budu mit v kodu volani $this->getUser()->getIdentity()->getUser() :D

Co vraci posledni volani getUser? Entitu uzivatele, ne? Tak proc to nepojmenovat getEntity?

hapi
Člen | 35
+
0
-

Patrik Votoček napsal(a):

Znovu se ptám Co to je Person/User? Předpokládám že člověka nebereš a neukládáš do DB :-) . Proto mě to celé připadá zmatené. Ty potřebuješ jednoznačnou identifikaci člověka tedy jeho Identitu. Ale asi těžko budeš používat člověka (ten přece sedí za počítačem a ovládá aplikaci).

Tak pokud to řešíme na této úrovni, pak ani produkt (třeba ledničku) neukládám do databáze. Ale Product reprezentuje ten konrétní reálný produkt. A Person/User mi přijde logičtější než Identity.

Takymi připadá logičtější aby Person/User měl objednávku a ne Identita. Jdeš do krámu pro rohlíky Ty nebo tvoje Identita.

A ve šech systémech co jsem do dnes viděl vždy byl Person/Member/User. A i pan Kravál na školení UML vždy používal tato označení.

Nevím co na co pokukazuješ. Tako pokud tato třída Person/Member/User bude implementovat rozhraní Identity, pak pro UI bude identitou Person/Member/User a pro plikaci jako takovou to bude objektově správně.

Nějak teď vůbec nechápu kam jsme se posunuli :)

Editoval hapi (17. 9. 2012 14:09)

hapi
Člen | 35
+
0
-

Elijen napsal(a):

Ale to pojmenovani je z meho pohledu nestatsne, protoze ve finale budu mit v kodu volani $this->getUser()->getIdentity()->getUser() :D

Co vraci posledni volani getUser? Entitu uzivatele, ne? Tak proc to nepojmenovat getEntity?

protože pokud název metody říká co přesně vrací, pak je to přeci líp pochopitelné i pro někoho kdo zdroják vidí poprvé. getEntity je strašně abstraktní. To může vrátit vpodstatě cokoliv. Co když je na identitu napojeno více entit?

Patrik Votoček
Člen | 2221
+
0
-

Jde me o to dopracovat se k tomu jaký je vastně ve tvém případě rozdíl mezi IdentityEntity vs UserEntity… Podle toho co jsi zatím napsal tak nevidím jediný důvod proč by:

  1. možnost
$user->getIdentity() instanceof UserEntity
  1. možnost
class PageEntity
{
	/**
	 * @orm\manyToOne(targetEntity="IdentityEntity")
	 */
	private $author;
}
  1. možnost

do $user->identity vůbec necpat entitu a pracovat s ní po svém

arron
Člen | 464
+
0
-

Osobně to mám od sebe jasně oddělený. Identitu vytvářím při autentizaci z UserEntity + si do ní ukládám nějaká další data o uživateli. Vidím výhodu v tom, že dokud je uživatel přihlášený, tak tu entitu nemusím při každém requestu znovu načítat. Zároveň se nemusí řešit problém při ukládání doctrine 2 UserEntity.

Nicméně když nad tím tak přemýšlím, tak název Nette\Security\User je opravdu trochu zavádějící, protože se jedná spíš o nějakou servisu nebo tak něco (která mimojiné dokáže ověřit práva a vrátit identitu aktuálního uživatele).

hapi
Člen | 35
+
0
-

Patrik Votoček napsal(a):

Ok, to beru, špatně jsem tě pochopil a to už i proto, že pokaždý když člověk napíše na nějaké fórum, tak se strhne flamewar o nesmrtelnosti brouka a tazatel se v podstatě nedozví, co chtěl.

no v podstatě jde o interní systém, kde UserEntity může být zákazník, dodavatel, zaměstnanec. UserEntity může mít služby různých typů, objednávky těchto služeb, požadavky atd atd. V podstatě se kolem uživatele točí úplně všechno.

UserEntitity obsahuje pouze základní, povinné údaje. A dále může obsahovat dalších X parametrů, jako dalsší telefonní čísla, e-maily apod.

Čili zde nejde jen o evidenci kvůli autorizaci, ale autorizace je jen jedna z mnoha funkcí systému.

Zatím se přikláník k možnosti:

UserEntity instanceof Identity

Editoval hapi (17. 9. 2012 19:26)

hapi
Člen | 35
+
0
-

arron napsal(a):
Nicméně když nad tím tak přemýšlím, tak název Nette\Security\User je opravdu trochu zavádějící, protože se jedná spíš o nějakou servisu nebo tak něco (která mimojiné dokáže ověřit práva a vrátit identitu aktuálního uživatele).

No a to mne prve hodně mátlo, opravdu myslím, že se na tom zasekne dost lidí, pokud to vidí poprvé.
V podstatě jde spíš o nějakou Auth službu, co mui řekne jestli je někdo přihlášen, jaká má práva a kdo to lastně je.

A už jen to že se mi getUser() vrací i v momentě, že User není znám. Ale nechci to překopávat. Pokud to tak v Nette bude i do budoucna, tak se s tím smířím :)

Aearsis
Člen | 57
+
0
-

Taky pozor na to, že Identita se serializuje do session. Doctrine entity se moc se serializací nekamarádí – obzvlášť pokud mají relace.

hapi
Člen | 35
+
0
-

Jasně, pokud budu entitě implementovat identitu, pak je potřeba upravit UserStorage

viz https://forum.nette.org/…-userstorage

Ale asi to dělat nebudu