Autor Zpráva
cesss
Profil *
Dobrý den,

mám docela velký problém a nevím, jak jej vyřešit.

Na mé webové aplikaci mám přihlašování řešeno přes relace (sessions) a mám to uděláno tak, že pokud je jeden uživatel na jednom účtu přihlášený, nemůže se přihlásit na druhý účet, dokud ten první neodhlásí.

Jenže problém je v tom:

Co dělat, abych zabránil vícenásobnému přihlášení na jednoho uživatele ze dvou počítačů?
Uživatel A se přihlásí z jednoho počítače na účet 'uzivatel'
Uživatel B se přihlásí z druhého počítače taktéž na účet 'uzivatel'

A budou pracovat souběžně - k čemuž v mé webové aplikaci NESMÍ dojít!

Jak by se to prosím dalo ošetřit?


Přemýšlel jsem, že bych mohl při přihlášení uživatele uložit jeho sessions ID do databáze přímo do tabulky uživatelé, tam by byla kolonka ses_id a v ní by byla 0 - tento uživatel není přihlášen nebo session ID = uživatel je přihlášen.

Pokud se na uživatele někdo bude snažit připojit, ověří se jeho sessions ID s tou v databázi. Pokud je stejná, může pokračovat... Pokud ne - uživatel bude odhlášen a v databázi se session ID nastaví na nulu. Tím pádem to odhlásí i původního přihlášeného.

Tohle by bylo i řešení toho, kdy uživatel zavře prohlížeč - v databázi zůstane přihlášený ale jeho sessions se po opětovném spuštění aplikace změní. Dojde k tomu, že se uživatel bude chtít na sebe opět přihlásit - jenže přihlášený v databázi bude a tím pádem ho to z databáze odhlásí. Poté se už bude moci zase přihlásit.

Problém je v tom, že tento způsob je dost NÁROČNÝ na databázi, jelikož se na KAŽDÉ STRÁNCE musí ověřovat, zda je sessions stejná jako ta uživatelova (a v databázi). To je strašně moc dotazů, když si vezmete, že ve webové aplikaci bude například 200 lidí.


Jak to tedy řešíte vy?

Mnohokrát děkuji za odpověď.


Vlastně, šlo by to řešit o něco jednodušeji..

U každého uživatele v databázi by byla kolonka PŘIHLÁŠEN = A (ano) N (ne)

Pokud se někdo bude snažit přihlásit na uživatele s A (ano), napíše mu to že uživatel je už přihlášen ať to zkusí znovu a přenastaví se to na N (ne).

Na každé stránce se bude ověřovat uživatelův nick v sessions s databází a kolonkou PŘIHLÁŠEN.
Pokud je uživatel přihlášen za uživatele Pepa a uživatel Pepa má v kolonce PŘIHLÁŠEN - N (ne), tak to uživatele odhlásí.

Ale pořád je to spousta dotazů.


Tak blbost, o sessions ID tam musí být, protože ten uživatel by toho druhého odhlásit nemusel v případě, že by ten druhý uživatel byl třeba zrovna na WC :D zůstal by přihlášený i potom... prostě by jen neobnovil stránku ale v databázi by bylo i po přihlášení prvního uživatele 'A'... takže by byli přihlášení oba...
Alphard
Profil
Při přihlášení uživatele odhlašte předchozí spojení. Samozřejmě je nutné při každém požadavku ověřovat oproti databázi.
Ale rovnou vám říkám, že uživatelé nadšeni nebudou. Nerozumím tomu, proč nejde pracovat najednou. Panely přece používáme běžně, proč vadí druhý počítač?
cesss
Profil *
Protože to bude hra... Nemůžou být 2 hráči na jednom účtu SOUČASNĚ...


Jinak, už jsem to naprogramoval, jen to někde vyzkoušet... ale opravdu dotaz na každé stránce.. no :\ naštěstí ty dotazy dělají jen přihlášení uživatelé (kontrola oprávnění)
Alphard
Profil
Neříkám 2 hráči, ale jeden hráč může chtít v krátkých časových intervalech střídat počítače.

Dotazu na databázi se nevyhnete, jediná možnost je použít jiné sdílené uložiště, ale to by asi moc nepomohlo. Nicméně u hry bude těch dotazů hádám stejně víc.
Keeehi
Profil
cesss:
Když se budu chtít přihlásit i na jiném počítači, tak mi stačí si nakopírovat tu session a jsem přihlášen 2x. Nevím, čemu by mělo vadit, že budou přihlášeni na dvou počítačích. Pokud to je hra třeba tipu trav*an, vícenásobné přihlášení ji neurychlí. Pokud je to hra jiného typu, kde hráč získá nějakou výhodu, pokud to poběží ve více oknech zároveň, jak pak chcete řešit spuštění ve více panelech na jednom počítači?
cesss
Profil *
Alphard:
Snažím se šetřit kde se dá, zatím mám 5 dotazů na každé stránce pro přihlášeného uživatele, což je relativně malinko oproti jiným, kde jsou až desítky dotazů (proto se někdy stránky načítají docela dlouho - například. 2 vteřiny i na rychlých strojích).

Keeehi:
Při přihlášení se kontroluje, jestli už uživatel není někde přihlášen. Navíc se před příhlášením mění session id (proti fixation).
Hra typu trav*an to není, nečeká se tam, je to real-time.

Pokud je jeden uživatel přihlášen ve dvou panelech, je stejně rychlý - pracuje stejně rychle - pořád to je jeden uživatel a udělá tolik práce jako jeden uživatel.
Pokud jsou 2 uživatelé přihlášení každý na svém PC, jeden může například vydělávat ve hře peníze zatímco druhý bude expit... Chápete? Udělají toho 2x více.
Magnus123
Profil
Ahoj.

Mohu mít dotaz? Proč vlastně vadí, když bude uživatel přihlášen na více jak jednom PC?

Edit:
Jak jsem to dopsal, objevila se mi odpověď. Nicméně, cituji: "Pokud jsou 2 uživatelé přihlášení každý na svém PC, jeden může například vydělávat ve hře peníze zatímco druhý bude expit... ". Osobně si myslím, že se to hráči kdovíjak nezrychlí. Já bych to jako veliký problém neviděl.
Ugo
Profil
cesss:
jestli dvojité přihlášení dává možnost dělat dvojnásob věcí, pak je něco špatně, případně .. jsi si jist že to umožní? Takhle mi to připadá jak kdyby logiku řešil javascript snad, v phpku přece děláš všechno s nějakym ID a dle toho máš i omezení který sou stejný ať běží 1 nebo 20 strojů. Jako kdybych měl wowko kde mi umožní víc přihlášení, neudělal bych nic navíc, jen bych se o ovládání pral, protože rozhodnutí dělá server a ne klient.
cesss
Profil *
Ugo:
ale ve wow to povolené není (souběžné přihlášení) a oni věděli taky proč. Navíc, ve wowku hraješ s určitou postavičkou... kdyby tam bylo souběžné přihlášení, ve hře se objeví postavičky DVĚ a radši si ani nepředstavovat, jak by to spolu kolidovalo...


Přesně to je případ taky browserové hry, kdy se jeden uživatel rozhodne něco udělat, ale udělá zároveň i to, co udělal druhý za něj přihlášený uživatel - a přitom o tom ani ten první nevěděl...

Příklad: Uživatel #1 je přihlášen za účet Pepa a rozhodne se, že půjde expit do oblasti 'temnyles'... expí expí a najednou se mu objeví zpráva od uživatele 'brambora' - ok sejdem sejdem se na tržišti.. pak se podívá do odeslaných zpráv a tam bude
Od uživatele 'pepa' pro uživatele 'brambora' - ahoj, chci si koupit 5kg brambor za 100Kč... máš zájem?

A přitom celou dobu expil v temném lese a ani nevěděl, že něco takového napsal.
Kdyby si zprávy nevšimnul, ten druhý uživatel mohl klidně za uživatele Pepa provést obchod zatímco by první uživatel celou dobu expil...
Ugo
Profil
cesss:
Právěže ne protože logika je na straně serveru (kde taky bejt musí) který si to ošetří, máš jeden účet ovládaný ze 2 míst. Moc bych se tím nezatěžoval, případně když to opravdu chceš, tak snad opravdu jedině hlídat a hlídat v každym dotazu.


ještě abys ušetřil dotazy tak můžeš udělat kompromis, ukládat si id aktivního přihlášení do session vždy když se dějě nějaká hlídaná akce. Co víš jen ty je, jestli by to nějak pomohlo když je to real-time :)
Alphard
Profil
cesss:
Kolik uživatelů najednou povolíte je mi jedno, ale to, co popisujete
Kdyby si zprávy nevšimnul, ten druhý uživatel mohl klidně za uživatele Pepa provést obchod zatímco by první uživatel celou dobu expil...
vypadá spíš na krádež účtu než na využívání více počítačů (fyzicky) jedním uživatelem najednou.
cesss
Profil *
.. nebo spolupráci, na jednom účtu (fyzicky)...

Vy ale pořád řešíte něco jiného místo mého původního problému, což nechápu. Nevíte, jak ta aplikace funguje, ale já vím, že pokud by bylo více uživatelů přihlášeno najednou, tak by to byl problém, jelikož to není klasická "čekací" hra, jakých je po internetu desítky. Bude to něco nového - realtime v prohlížeči v PHP...

Takže si to můžete představit jako klienta například zmíněného WOWka a tam je NUTNÉ, aby byl účet přihlášen naráz jen JEDENKRÁT z JEDNOHO místa, nikoliv více.

Už to mám naprogramované a vše funguje jak má - odzkoušeno na 2 PC. Když je uživatel někde přihlášen a někdo ho odněkud logne, odhlásí to ten účet - takže i toho prvního uživatele.

Jako by se vám ve Wowku objevilo "You logged in from another location, logging out in 5 seconds"...

A tomu "loggerovi" se napíše, že účet je už přihlášen.


*Solved*
Amunak
Profil
cesss:
Víš to, že pokud to opravdu funguje tak, že "když klikám víc jsem lepší", nejspíš se velmi brzy najde někdo, kdo si na to napíše robota?
Alphard
Profil
Zamykám to tady, autor to evidentně řešit nechce, je to jeho věc. Omlouvám se, že jsem dal podnět k této diskusi.
Toto téma je uzamčeno. Odpověď nelze zaslat.