Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Wielokrotne logowanie
Forum PHP.pl > Forum > PHP
R4D3K
Witam, na początku chce zaznaczyć, że to nie jest problem poruszany n-ty raz, przeszukałem koło 100 tematów na tym forum dotyczących logowania i nie znalazłem odpowiedzi, google milczało, chyba że nie wiem jak zadać pytania dla wujka google, jeśli tak to przepraszam. wstydnis.gif

Posiadam stronę na której jest galeria ze zdjęciami i aby można było je obejrzeć użytkownik musi być zalogowany i mój problem polega na tym iż 1 osoba się rejestruje i podaje reszcie swój login i hasło i jednocześnie oglądają zdjęcia. Z praktyki wiem że w jednym czasie na 1 loginie przegląda zdjęcia nawet 4 użytkowników jednocześnie. Chcę to wyeliminować i zmusić każdego z tych użytkowników to założenia konta.

Na podstronie z galerią sprawdzam, czy osoba jest zalogowana za pomocą sesji:

  1. <?php
  2. if (isset($_SESSION['id'])) {
  3. // pokaz galerię
  4. }
  5. else {
  6. // powiedz userowi że musi się zalogować
  7. }
  8. ?>


próbowałem używać
session_regenerate_id()" title="Zobacz w manualu PHP" target="_manual , także dodałem regułę do pliku htaccess:
Kod
php_value session.use_only_cookies 1
php_value session.use_trans_sid 0

Oczywiście pozwoliło to wyeliminować spryciarzy, którzy przesyłali link już po zalogowaniu, ale dalej mojego problemu to nie rozwiązało.
Myślałem o tym,żeby stworzyć tabelę z id_usera i id_session i sprawdzać co każde wylistowanie zdjęć czy id sesji zgadza się z orginałem.
Jednak czy to pomoże czy tylko obciąży serwer ? Czy może lepiej wysyłać jakieś ciasteczko, czy też sprawdzać odstęp czasu pomiędzy logowaniami
czy w jakiś sposób sprawdzać czy dany użytkownik jest zalogowany ? (jeśli tak to w jaki ?)

Prosiłbym tych, którzy spotkali się z tym problemem, żeby opisali jak sobie z tym poradzili, może ktoś wklei jakiś kawałek kodu
Z góry dzięki
maly_swd
Podczas logowania zapisz IP na ktorym jest zalogowany dany login:) Jesli login nie zgadza sie z IP to musi sie zalogowac:)
R4D3K
@maly_swd to za bardzo problemu nie rozwiąże, bo przeważnie logują się na 1 loginie Ci z tego samego "osiedla" co się wiąże z tym, żę mają takie samego providera -> ten sam adres IP. Wiem to po logach.
Wicepsik
Może identyfikacja przez MAC ?
1 konto = 1 MAC
kfc4
Zapisujesz w bazie login i id sesji. Jak ktoś się loguje to sprawdzasz czy taki login już istnieje w tabeli (po np. pół godzinie nie aktywności kasujesz rekord (sprawdzasz pole w którym zapisujesz ostatnią aktywność)), jak tak to porównujesz z id sesji, jeżeli są różne to wywalasz komunikat, że musi mieć własny login, jak się zgadza to przepuszczasz. Aby zapobiec użytkownikom, wyłączającym komputer bez wylogowania i włączającym go za 15 minut możesz w ciasteczkach trzymać coś indywidualnego np. time+nazwa przeglądarki i to porównywać zamias id sesji.

Ja kiedyć porówynywałem ciasteczko z zawartością w bazie, rekord kasowałem po 30 minutach nie aktywności (razem z ciasteczkiem).
MateuszS
Zrob przy rejestracji ciasteczko ktore tam ma czas time()+9999999999999999 i potem sprawdzaj przy logowaniu czy to ciacho istnieje jak nie to niech koles spieprza
kfc4
Mateusz: nie wypali pomysł bo:
-zmiana komputera;
-przeglądarki;
-format;
-logowanie u kogoś innego;
-wyczyszczenie danych prywatnych
-i jeszcze parę innych
MateuszS
kfc4,
trzeba by sie nad tym glebiej zastanowic
dworakex
Do tabeli z userami dodajesz pole "sid" gdzie zamieszczasz identyfikator sesji i pole "time" gdzie wstawisz czas w timestamp. Przy logowaniu każdy dostaje sida, którego dodajemy do bazy danych. Jeśli aktualny timestamp będziewiększy od "time"+1800 (czyli jesli przez pol godziny nioe będzie zadnej akcji" to zmieniasz "sid" na 0. Przy logowaniu sprawdzamy czy "sid"==0. Dodajesz też opcję wyloguj, która też ustawia SID na 0.
R4D3K
@Wicepsik
Jak zrobić porównywanie adresu MAC w PHP ?

@dworakex
Zapisywanie w tabeli id sesji, też na tym myślałem, ale tu pojawia się problem z początku, osoba nie zalogowana uzyska dostęp tam gdzie nie powinna. Wystarczy się zalogować, wyłączyć cookie i przesłać komuś linka z PHPSESSID, także trzeba co każde wyświetlenie strony korzystać z session_regenerate_id(), co wyklucza porównanie z id sesji w bazie.

@MateuszScirka
Cytat
]Zrob przy rejestracji ciasteczko ktore tam ma czas time()+9999999999999999 i potem sprawdzaj przy logowaniu czy to ciacho istnieje jak nie to niech koles spieprza

Właśnie do mnie wchodzą tacy cfaniacy co sobie z tym radzą.
dworakex
Dlaczego nei regenerować id? Albo wymusić stosowanie ciasteczek, albo możesz co 10 kliknięć robić "Wpisz haslo:". W każdym razem, mogą hasło sobie popodawać, to wtedy masz znoka, będą naraz wszyscy tongue.gif
R4D3K
Hmmm no tak regenerować id sesji mogę to co wtedy z zapisywaniem id sesji do bazy za każdym razem to robić ? Trochę chyba nieoptymalne
erix
Cytat
Może identyfikacja przez MAC ?
1 konto = 1 MAC

Na głowę upadłeś?

Z tego, co pamiętam, to MAC jest tylko w warstwie łącza danych. tongue.gif
R4D3K
Tak PHP jako język po stronie serwera nie ma dostępu do zasobów komputera lokalnego.
@erix może wiesz jak rozwiązać ten problem ?
pgrzelka
temat pobierania adresu mac jest poruszony w Archiwum Pro
Temat: MAC_zamiast_IP

z tymi sesjami to też nie najgorszy pomysł, zapisuj login lub ip do sesji a najlepiej obie zmienne i pilnuj aby te wartości się nie powtarzały,
czyli jeśli ktoś o loginie 'maniek' jest zalogowany to przy logowaniu z innego komputera loginem 'maniek' sprawdzasz czy już taka osoba nie jest zalogowana

jeśli bardzo namieszałem to przepraszam winksmiley.jpg
erix
Adres MAC, to kiepski pomysł, gdyż w przypadku proxy/NAT/tunelu nie masz MAC delikwenta. Poza tym, MAC da się zmienić (niektórzy wciąż żyją w błogiej nieświadomości, że się nie da tongue.gif)
R4D3K
@pgrzelka dzięki za info, gdyby nie ty dalej był żył w przekonaniu, że się nie da MAC adresu wyciągnąć i tyle, nawet jeśli chodzi o korzystanie w sieci lokalnej.

Może trochę naświetle problem bardziej, stworzyłem sobie stronę gdzie można znaleźć zdjęcia itp w PHP, wykupiłem płatny hosting zamieściłem pliki.
Strona ma "zasięg" jeśli tego słowa można użyć, "miastowy" to znaczy zdjęcia są robione z imprez w moim mieście z tego powodu 90% ruchu na stronie pochodzi z mojego rodzimego miasta. Jeśli chodzi o dostawców usług internetowych, tam gdzie mieszkam liczą się 2 gracze: Neostrada i Vectra(taka sieć kablowa dostarczająca internet razem z kablówką). Podobnie jak Neostrada, Vectra przydziela adresy IP dynamicznie, w obrębie danej dzielnicy, czyli jedno osiedle ma na wyjściu ten sam adres IP (sprawdziłem). Jedno takie osiedle to ładna liczba użytkowników. Dlatego tak się wystrzegałem weryfikacje przez ip.
Jak narazie wymyśliłem, taki oto sposób wykluczenia wielokrotnego logowania w 1 czasie:
Tworzę tabelę z id_user, sid,time i gdy dany user próbuje się zalogować sprawdzam czy w tej tabeli nie ma wpisu z jego ID, jesli jest to sprawdzam, czy jego id sesji jest równe wartości pola sid, jeśli jest to każę mu się zalogować, jeśli nie to go loguje tworząc odpowiedni wpis w bazie danych. Trochę to zawiłe, więc może użyje pseudokodu:
  1. <?php
  2. if (isset($_POST['login'])) {
  3. // user chce się zalogować
  4.  $dane=mysql_fetch_array(mysql_query('SELECT * FROM session WHERE id_user=SELECT id FROM users WHERE login=$_POST['login'] AND pass=md5($_POST['pass']))
  5.    if ($dane['sid]==session_id()) {
  6.    // Mam cię spryciarzu teraz grzecznie załóż konto i się zaloguj
  7.  }
  8.  else {
  9.   // OK zaloguj się i uaktualnij tabelę session
  10.  }
  11. }
  12. ?>


I co myślicie czy ten sposób jest OK ? Bo ja tu widzę problem z łatwością przejęcia takiej id sesji, ponieważ session_regenerate_id()" title="Zobacz w manualu PHP" target="_manual nie będzie wykorzystywane i ciągle muszę uaktualniać wpis w tabeli session. No chyba że się mylę, lub jest jakiś sposób żeby nie przesyłac tylu zapytań.
erix
  1. skrypt jest dziurawy (SQL Injection)
  2. MD5 też można "odwrócić"
  3. Cytat
    Jak narazie wymyśliłem, taki oto sposób wykluczenia wielokrotnego logowania w 1 czasie:
    • ukryte ciastko z długim czasem ważności
    • sprawdzanie User-Agent
Tyle mi na razie przyszło do głowy
R4D3K
dzięki erix, to że jest dziurawy to wiem już nie dodawałem tutaj zabepieczeń
MolTAR
A nie można by do tabeli z użytkownikami dodać pola 'zalogowany'. Jeśli zaloguje się to zalogowany = 1 jeśli wyloguje to zalogowany = 0, po przekroczeniu czasu sesji tak jak wcześniej pisaliście tam zalogowany znów = 0. I sprawdzać przy logowaniu czy przy tym userze jest 'zalogowany' = 1 czy 0 jeśli 1 to wywalić komunikat: "jesteś już zalogowany".
Jeden login = jeden komputer.
R4D3K
A jeśli użytkownik nie kliknie "WYLOGUJ" tylko zamknie przeglądarkę to i dalej zostanie w bazie zalogowany=1 ?
MolTAR
zdarzenie zamykania przeglądarki z tego co wiem można chyba jakoś w js przechwycić i wtedy ajaxem zmienić wartość 'zaloguj' na 0
bełdzio
Cytat(R4D3K @ 2.07.2009, 23:18:33 ) *
A jeśli użytkownik nie kliknie "WYLOGUJ" tylko zamknie przeglądarkę to i dalej zostanie w bazie zalogowany=1 ?

zawsze możesz zapisać czas ostatniej akcji i co jakiś czas odpalać GC
R4D3K
GC ? chodzi o tą odśmieciarkę ? Bełdzio możesz rzucić jakimś kodem ?
erix
Cytat
zdarzenie zamykania przeglądarki z tego co wiem można chyba jakoś w js przechwycić

Taa... W praktyce już nie jest tak idealnie...

Cytat
GC ? chodzi o tą odśmieciarkę ?

Nie; po prostu ustalasz czas nieaktywności, po którym sesja jest uznawana za martwą.
MolTAR
Możesz też dać użytkownikowi ciasteczko na taki czas po jakim następuje wylogowanie po nieaktywności. Jeśli zaloguje się, później wyłączy przeglądarkę i znów włączy Twoją stronę to będzie się mógł zalogować pod warunkiem że będzie miał to ciasteczko jeśli go nie będzie miał to komunikat 'jesteś już zalogowany'. Problem w tym, że jak ktoś usunie ciasteczka to nie wejdzie przez jakiś czas na stronę. Ale to chyba nie jest tak bardzo prawdopodobne, bo ludzie nie usuwają ciasteczek tak często, a większość nawet nie wie co to jest.
R4D3K
Dobra, ale tak myślałem żeby zamiast ciasteczka użyć session_cache_expire()" title="Zobacz w manualu PHP" target="_manual
Wyglądały by to tak:
* ustawiam sobie czas np 30 minut "życia sesji"
* przy logowaniu zapisuje sobie do zalogowany= time(), jeśli będzie zero znaczy ze nie jet zalogowany jeśli będzie coś innego =>zalogował się
* przy próbie logowania sprawdzam pole zalogowany i porównuje czasy.
* Jeśli czas zalogowania jest mniejszy jak 30 minut to znaczy, że user jest zalogowany już.

Tylko mam takie pytanie czy da się sprawdzić, ile czasu jeszcze zostało do wygaśnięcia danej sesji ?
rzymek01
moim zdaniem:
- sesje PHP wraz z własnym mechanizmem w bazie
- czas życia sesji
- może być regeneracja id co stronę
- w ciastku zapisujesz id sesji oraz unikalny ciąg znaków skrócony np. przez sha1, w którym zbierasz wszystkie dane przy logowaniu jakie się da - user agent, ip, Accept, Accept-Language, Accept-Charset, Accept-Encoding haha.gif
bełdzio
takie cos mi jeszcze w lozku przyszlo do glowy ;-)

user sie loguje -> zapisujesz sesje w bazie -> kolejny user się loguje -> spr czy w bazie jest sesja użytkowniwka o takim samym ID -> jeśli jest to ją kasujemy

w taki sposób zawsze bedzie zalogowany jeden user + za kazdym razem jak bedzie chcial sie zalogowac ktos na jego dane to go wyloguje :-)

jak będzie "martwa" sesja to nic się nie stanie, jak będzie zalogowany inny user to się troche podenerwuje i przemyśli kwestię dawania swoich danych innym :-)
fander
Cytat(bełdzio @ 3.07.2009, 12:20:40 ) *
takie cos mi jeszcze w lozku przyszlo do glowy ;-)

user sie loguje -> zapisujesz sesje w bazie -> kolejny user się loguje -> spr czy w bazie jest sesja użytkowniwka o takim samym ID -> jeśli jest to ją kasujemy

w taki sposób zawsze bedzie zalogowany jeden user + za kazdym razem jak bedzie chcial sie zalogowac ktos na jego dane to go wyloguje :-)

jak będzie "martwa" sesja to nic się nie stanie, jak będzie zalogowany inny user to się troche podenerwuje i przemyśli kwestię dawania swoich danych innym :-)


Albo inaczej gdy znajdzie użytkownika o takim samym id ale innej sesji to wyświetla komunikat o tym ze ktoś wisi na jego koncie.
R4D3K
Cytat
Albo inaczej gdy znajdzie użytkownika o takim samym id ale innej sesji to wyświetla komunikat o tym ze ktoś wisi na jego koncie.

A co z session fixiaton i koniecznością session_regenrate_id()" title="Zobacz w manualu PHP" target="_manual
crackcomm
Gdy użytkownik się loguje SID jest dodawany do bazy i do cookie, gdy to się zgadza może sobie chodzić. Gdy ktoś następny się zaloguje (użytkownik2) to znów zapisuje się SID (inny niż poprzedni) w bazie i w cookiesach. Użytkownik już nic nie może zrobić bo jest wylogowany i musi się znów zalogować, loguje się wtedy wylogowuje użytkownika2 itd. itd. smile.gif
rzymek01
Cytat(crackcomm @ 4.07.2009, 20:12:55 ) *
Gdy użytkownik się loguje SID jest dodawany do bazy i do cookie, gdy to się zgadza może sobie chodzić. Gdy ktoś następny się zaloguje (użytkownik2) to znów zapisuje się SID (inny niż poprzedni) w bazie i w cookiesach. Użytkownik już nic nie może zrobić bo jest wylogowany i musi się znów zalogować, loguje się wtedy wylogowuje użytkownika2 itd. itd. smile.gif

ale sęk w tym, że to za mało, bo - z tego co zrozumiałem - są to zaprzyjaźnieni userzy i mający nieco pojęcie o kompach, więc jeden może podać drugiemu całe ciastko i już może chodzić jako zalogowany

sposób @bełdzia jest prawie idealny, bo zostaje możliwość cały czas chodzenia jednym userem (ale tylko jeden w jednym czasie), więc do tego bym dodał zbieranie i sprawdzanie user-agentów itp. tongue.gif
Kethrax
Witam,

Ja bym zrezygnował wogóle z cookies.

User loguje się (login, hasło) jeżeli poprawne logowanie w bazie zapisuje się "secretUserCode" generowany jest tak:
  1. <?php
  2. $userSecretCode = md5($usrPass.session_id().date("YmdH:i:s"));
  3. //dodanie do bazy -> $userSecretCode
  4. $_SESSION['userSecretCode'] = $userSecretCode;
  5. ?>


Później sprawdzanie przy otwieraniu każej strony czy $_SESSION['userSecredCode'] jest identyczny z tym w bazie.
Jeżeli ktoś będzie się próbować zalogować na już zalogowanego usera, komunikat że już jest ktoś zalogowany.
  1. <?php
  2. if (userSecretCode z bazy != "locked") throw new Exception("Nie można zalogować");
  3. else { //logowanie }
  4. ?>

Przy wylogowaniu userSecretCode jest zastępowany np. "locked" i session_destroy();

W przypadtku gdy user nie kliknie wyloguj, Ajax.
crackcomm
Cytat(rzymek01 @ 5.07.2009, 09:19:39 ) *
ale sęk w tym, że to za mało, bo - z tego co zrozumiałem - są to zaprzyjaźnieni userzy i mający nieco pojęcie o kompach, więc jeden może podać drugiemu całe ciastko i już może chodzić jako zalogowany

sposób @bełdzia jest prawie idealny, bo zostaje możliwość cały czas chodzenia jednym userem (ale tylko jeden w jednym czasie), więc do tego bym dodał zbieranie i sprawdzanie user-agentów itp. tongue.gif

W sumie to co napisał Bełdzio...to jest to samo co napisałem ja tongue.gif
rzymek01
Cytat(crackcomm @ 5.07.2009, 15:24:20 ) *
W sumie to co napisał Bełdzio...to jest to samo co napisałem ja tongue.gif

z tego powodu, że @Bełdzio pisał pierwszy, to chyba Ty napisałeś to, co już wcześniej napisał Bełdzio, ale mówię, że jeszcze ja bym sprawdzał inne dane, które da się wyciagnąc, np. user-agent

@Kethrax, "Ja bym zrezygnował wogóle z cookies."
a sid w pasku adresu? haha.gif
bełdzio
Cytat(rzymek01 @ 5.07.2009, 15:30:51 ) *
z tego powodu, że @Bełdzio pisał pierwszy, to chyba Ty napisałeś to, co już wcześniej napisał Bełdzio, ale mówię, że jeszcze ja bym sprawdzał inne dane, które da się wyciagnąc, np. user-agent


inne dane nic nie dadzą bo nie są unikalne, a z tego co kojarze to problem polegał na tym, żeby jednocześnie nie można było zalogować się na jeden login przez wielu userów, co też moje rozwiązanie robi ;-)
R4D3K
Dzięki Wam za odpowiedzi.
Najbardziej podoba mi się sposób Bełdzia, zapisanie sid sesji do bazy, też o tym pisałem w pierwszym poście, tylko panowie z tym sposobem jest jeden ból: przesłanie linka z id sesji np http://example.com?PHPSESSID=... Użytkownicy są cwani, ale nie na tyle żeby sobie ciastka przesyłać, wiem bo mi kolega co zgłaszał ten problem przesłał właśnie linka z sesją przez gg.
Jeśli dodam od razu po sprawdzeniu czy user jest zalogowany, session_regenerate_id to user który działa na stronie jako 2 wyloguje usera 1 ( dobrze mówię ?), i pytanie czy ta reguła w pliku htaccess :
Kod
php_value session.use_only_cookies 1
php_value session.use_trans_sid 0

Rozwiąże problem przesyłania id sesji w linku ? Nawet jak user wyłączy ciastka ?
rzymek01
Cytat(R4D3K @ 5.07.2009, 23:27:28 ) *
Nawet jak user wyłączy ciastka ?

nie będzie miał możliwości zalogowania się smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.