Sesje w PHP

0

Czesc, czytam, czytam o tych sesjach to postanowilem cos sprobowac z tym zrobic. Pobralem sobie Codeigniter i postanowilem cos napisac. Jak widac, chyba nie bardzo wiem jeszcze o co chodzi w sesjach. Robie system logowania, przykladowo mamy funkcje logIn() ktory zwraca usera, po tych danych co wpisal w inputach i jesli sa zgodne to (sesja sie zaczyna). I teraz wlasnie jest to, czego nie rozumiem.

Kazdy uzytkownik, ktory zaloguje sie do systemu powinien miec inna sesje, prawda? I teraz moje pytanie, dosc noobskie, ale jestem poczatkujacy jesli chodzi o backend. Sesja rejestruje dany komputer, tak? A drugie pytanie, to czy jest to prawidlowe, ze id sesji przechowuje w bazie? Oraz jeszcze jedno pytanie, sesja w Codeigniter zmienia sie co 5 minut, to czy powinienem co 5 minut updateowac baze z idsesji, a jesli tak, to jak tego dokonac?

Z gory dziekuje, poczatkujacy Lukasz.

0

A nie lepiej użyć ciasteczek ?

0

Ogolnie pisze aplikacje rest i caly czas mam jakies watpliwosci w poprawnego dzialaniu tego. A mianowicie:

Jest strona z logowaniem, wysylam requesta do. np. (api/auth), nasze api powinno poszukac uzytkownika i stworzyc (token?) - tutaj pojawia sie pytanie, jak stworzyc taki token w php, tak aby go rejestrowac rownie jak sesje, bo wszedzie w tutorial widze, ze ludzie tworza** sesje['token'] = md5(i jeszcze wiecej algorytmow) **, na koniec myslalem aby zrobic tablice sesji i tam wepchnac ten token oraz id zwroconego usera.

Na koniec pobrac nasze response z api/auth i storzyc cookie z naszym tokenem i w naszym callbacku zrobic kolejny request do api/users/me, ktory zwraca dany rekord po id_usera w naszej sesji.

Pozniej do naszych kolejnych requestow w headerze bedzie nasz token, ktory bedzie sprawdzany czy jest taki sam jest sesyjny token, jesli jest to bedzie zwracal to co musi a jesli nie, to jakis http error.

Wydaje sie wszystko fajnie, ale nie wiem jak zniszczyc ta sesje po wylaczeniu przegladarki, bo ciasteczko sie usunie, ale sesja zostanie. Bo jesli zniszcze sesje przy api/logout, to wiadomo ze ja zniszczymy, ale przy zamknieciu przegladarki juz nie, to jest jedno co mnie nurtuje, a drugie to, czy to jest poprawne ze moj token jest w sesji, ale nie wiem jak w phpie inaczej sledzic nasze poczynania.

0

Jest strona z logowaniem, wysylam requesta do. np. (api/auth), nasze api powinno poszukac uzytkownika i stworzyc (token?) - tutaj pojawia sie pytanie, jak stworzyc taki token w php, tak aby go rejestrowac rownie jak sesje, bo wszedzie w tutorial widze, ze ludzie tworza sesje['token'] = md5(i jeszcze wiecej algorytmow) , na koniec myslalem aby zrobic tablice sesji i tam wepchnac ten token oraz id zwroconego usera.

$token = $baza->query("select id,login,haslo from users where login = '$login' and haslo = '$haslo' ");
$token = mysqli_fetch_array($token);

//tutaj będzie tworzony eniwersalny token na okres 1H
setcookie("token",$token[0],time()+3600);
setcookie("login",$token[1],time()+3600);
setcookie("haslo",$token[2],time()+3600);
 
1

Napiszę tu dość jasno bo widać tu jak na dłoni problemy ze zrozumieniem jak działają sesje. CodeIgnither ma (przynajmniej standardowa wersja do pobrania) cztery rodzaje sesji: FileBased, Database, Memcached, Redis. Domyślnie jest to Filebased, sesje są zapisywane w application/sessions.

Session ID jest unikalnym identyfikatorem generowanym w session_start, chyba na bazie aktualnego czasu i paru innych rzeczy, jest to także zapisywane w ciasteczkach bo skąd ma niby appka wiedzieć do którego z plików zapisywanych w application/sessions się odwołać? Sesje i ciasteczka mają swój czas życia. Generalnie sesje można oprzeć nawet na ciasteczkach, z tym że nie ma tu unikalnego ID. Tak też jest np. w Kohanie.

Mam system logowania CI na bazie Tank_auth, tam jest po prostu tak, że sesje są używane w celu zapamiętania tego że user jest zalogowany, jest też możliwość zapamiętywania na jakiś czas, do tego celu używana jest odpowiednia tabela w bazie.

Co do RESTful serwisu, ten token to można sobie wygenerować jako md5 albo sha1 na podstawie danych konkretnego zarejestrowanego użytkownika, tak aby przykładowe pobieranie danych przez GET

np. http://api.costam.com/costam?token=xxxxxxxxxxxxxxxxxxxx&limit=10

mogło pobrać dane np. w postaci JSON a ten token jest używany tylko po to, żeby uniemożliwić pobranie danych komuś innemu kto tego nie zna.

CodeIgnither jest dla mnie syfem, więc nawet nie zamierzam próbować coś takiego zrobić, natomiast w Kohanie mógłbym takie coś zrobić dość prosto, no ale to dlatego że dobrze go znam :-)

0

Przesiedzialem wczoraj nad tymi sesjami i mysle, ze coraz bardziej je rozumiem, widze teraz moje bledne myslenie, ale nadal nie rozwiazuje to mojego problemu, a mianowicie bezpiecznego dzialania client-server webservice. Macie moze jakies dobre artykuly o bezpieczenstwie za pomoca tokenow, webserwisow, tak abym mial glowny pojecie o tym.
Mam po prostu pewne luki, zastanowienia co do tego.

Chociazby, zastanawia mnie fakt przechowywania takiego tokenu w backendzie, czy tez ma on miec ustawiony jakis czas zycia, a jesli tak, to jesli on wygasnie, jak przekazac to do frontu, bo zalozmy ze we froncie w headersach jest nasz stary token, ale jesli zrobi request to juz nie bedzie sie zgadzal z tym nowym. Gdzies czytalem, ze jest to zrobione w ten sposob, ze po uplywie jakiegos czasu owszem tworz sie nowy token, ale stary rowniez zostaje bo czeka on na request, jesli uzyska request dopiero pozniej przekazuje dane wraz z nowym tokenem.

Takze chcialbym troche o tym poczytac, tylko nie wiem jakie zrodla sa warte uwagi.

0

Ale o co Ci w ogóle chodzi? To można zrobić tak. Masz w bazie danych takie dane jak id, swój login, hasło i np. data rejestracji i na podstawie tego generujesz sobie token jako dajmy na to SHA-256, to będzie na bank bezpieczniejsze niż np. md5 czy tam SHA1, ponieważ w SHA-256, używając w PHP hash_hmac masz jeszcze sól, tutaj stosujesz jakiś tam losowy ciąg znaków i pewnej długości.

Token generujesz dajmy na to przy rejestracji jako user albo np. gdzieś tam jako opcja w swoim panelu admina. To będzie zapisane w bazie, potrzebna będzie jakaś dodatkowa tabela user_tokens albo api_tokens, żeby przypadkiem się nie kłóciło czasem bo user_tokens to możesz mieć chociażby po to żebyś się mógł logować do serwisu z automatu bo wcześniej zaznaczyłeś zapamiętaj.

Masz więc w bazie ten swój REST api token jako SHA-256 na podstawie tych swoich danych w tabeli users, możesz to wykorzystać tak jak to przedstawiłem w poprzednim poście. Z tym że po prostu sprawdzasz token podany w parametrze URL z tym co jest w bazie. Co tu nie jest jasne?

Można oczywiście ustawić ważność na jakiś czas ale jak wygaśnie to będziesz musiał przecież wygenerować nowy, a stary przy tym usunąć. Ja tu cały czas mówię o pobieraniu jakichś JSON-owych danych przy użyciu GET a nie POST, bo POST-em to tutaj mógłbyś sobie wstawiać jakieś nowe dane, przez PUT je uaktualniać a przez DELETE usuwać, korzystając przy tym i tak z tego samego URL.

Ty tu chyba piszesz o jakichś danych, które może pozyskać tylko ten kto dysponuje pewnym kluczem. Tutaj wydaje mi się że jest to dobre podejście, bo masz token SHA-256 na bazie Twoich danych jako zarejestrowanego użytkownika, token znasz tylko Ty a nikt inny i strzeżesz tego tak jak hasło.

0

Ja wiem o co chodzi, chyba sie nie rozumiemy. Bo tak tez jest na fb. W cookiesach wartosc pod 'xs' to pewnie ten token i jesli zapamietam haslo to ciagle mi zapamietuje te dana wartosc, natomiast jesli jest bez tego to cookies sie zmienia co kazde logowanie. I tutaj chodzi mi o to, ze jesli sie wyloguje to cookies sie usunie bo taka ma ceche ale nasz token w bazie, ten stary zostaje, to co mam go nadpisac na ten co wygeneruje nowy?

To raz, a dwa ze jak odwolywac sie do tego tokena w tych rest controllerach. Bo zalozmy headerami od frontu idzie ten token z cookiesow (tak jak np.fb) a pozniej musze sprawdzic jego poprawnosc zanim zrobie requesta poprawnego, czyli zalozmy.

$app->get('/local/auth',function(){
Class User {

}
});
0

Ja wiem o co chodzi, chyba sie nie rozumiemy. Bo tak tez jest na fb. W cookiesach wartosc pod 'xs' to pewnie ten token i jesli zapamietam haslo to ciagle mi zapamietuje te dana wartosc, natomiast jesli jest bez tego to cookies sie zmienia co kazde logowanie. I tutaj chodzi mi o to, ze jesli sie wyloguje to cookies sie usunie bo taka ma ceche ale nasz token w bazie, ten stary zostaje, to co mam go nadpisac na ten co wygeneruje nowy?

To raz, a dwa ze jak odwolywac sie do tego tokena w tych rest controllerach. Bo zalozmy headerami od frontu idzie ten token z cookiesow (tak jak np.fb) a pozniej musze sprawdzic jego poprawnosc zanim zrobie requesta poprawnego, czyli zalozmy.

$app->get('/local/auth',function(){
Class User {
 protected function logIn(){
 // tutaj beda przesylane nasze dane z frontu, pomijam funkcjonalosc
 if($user){
      $this->generateToken();
    }// jakis tam else
}
protected function generateToken(){
//tutaj bedzie insert do bazy o ten token
}
protected function isAuth(){
    //tutaj bedzie sprawdzanie czy header auth od frontu jest zgodny z wygenerowanym tokenem
  }
}
});

I pozniej zalozmy stworzymy klase Rest extends User i do kazdego requestu mam sprawdzan metode isAuth?

Btw. dajcie mozliwosc edytowania anonimowym userom ;p

0

Ale ten token co ja napisałem ma związek z Twoim loginem i hasłem i np. ID w bazie, z założenia więc jego zmiana następuje dopiero jak np. zdecydowałbyś się zmienić hasło do logowania. Ty piszesz o czymś zupełnie innym, co ma związek np. zapamiętywaniem danych na jakiś czas, tak żebyś nie musiał za każdym odświeżeniem tego facebooka wpisywać swoich danych do logowania.

0

Ty piszesz o czymś zupełnie innym, co ma związek np. zapamiętywaniem danych na jakiś czas, tak żebyś nie musiał za każdym odświeżeniem tego facebooka wpisywać swoich danych do logowania.
Chyba doszlismy do porozumienia, bo o to mi wlasnie chodzi, chcialem zrobic cos podobnego na wzor facebooka, zeby ten token sie generowal i na jego podstawie mogl robic restowe operacje, bo jesli np. go zmienie to jest wylogowanie. Wiec jesli ktos sobie w cookiesach zmieni, a moje isAuth sprawdza tego delikwenta w bazie i widzi ze token wygenerowany jest inny niz ten przychodzacy w headearsach to np. robimy 401.

Tylko teraz chodzi mi o to, czy po pierwsze to co wypisalem do gory jest sensowane, to raz. A dwa, ze jesli wylacze przegladarke to jak jestem w stanie usunac ten poprzedni token.

0

Napiszę może lepiej na bazie Kohany bo dobrze go znam a CI słabo, jak i inne frameworki także. W Kohanie masz moduł Auth, który ma także driver ORM, więc musisz mieć też moduł Database oraz ORM. Moduły są w katalogu modules. Logowanie działa przy użyciu tabel: users, user_tokens, roles, roles_users oraz przy użyciu sesji, domyślnie jest to sesja natywna, więc serializowane dane są po prostu zapisywane w plikach sess_xxxxxxxxx a xxx to session_id w session_save_path, np w jakimś katalogu tmp.

Jeśli nie zaznaczę opcji "zapamiętaj mnie", to po zalogowaniu moje dane jako zalogowanego użytkownika są zapisywane w sesji i tylko z tego będą sprawdzane, przy czym domyślnie też Session lifetime jest ustawione na 0, co oznacza że taka sesja wygasa w przypadku zamknięcia przeglądarki, ma to oczywiście związek z tym że czas życia cookie, do którego jest zapisywane session id jest wtedy ustawiany na zero. Wystarczy przejrzeć kody żeby do tego dojść. Dopóki więc mam uruchomioną przeglądarkę to nie muszę się za każdym razem logować bo user jest brany z aktywnej sesji. Z tym że coś czytałem, że działa to chyba tylko przez godzinę, nie wiem, nie sprawdzałem.

W tym Twoim przykładzie wystarczyłoby chyba po prostu tworzyć ten token także w sesji, z czasem życia Session lifetime = 0, wówczas ten token także wygasa przy zamknięciu przeglądarki, tutaj zakładam że Ty chcesz korzystać z RESTful serwisu po prostu za pomocą tej samej przeglądarki a nie innej bo już nie zadziała. Co do cookie, jak ustawisz np. czas życia na dajmy na to 12h w tym czasie zamkniesz przeglądarkę i jeszcze potem w ciągu tego czasu uruchomisz, ciasteczka masz jeszcze ważne, więc odczytasz dane.

Tak to tutaj widzę. Łatwiej jest coś zrealizować jak się dobrze zna framework i to jest podstawa, bo jak nie znasz tego CI, czy tam dowolnego innego frameworka i nie wiesz jak działa auth i inne rzeczy to o czym my tu w ogóle mówimy? Będziesz się męczył i prosił o pomoc a i tak będą problemy, dopóki nie załapiesz dokładnie jak to wszystko działa.

0

Idac ta polityka https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/ moge wyslac httponly cookie do mojej apki z automatu wysylajac posta do np. '/auth', a pozniej w kazdym kolejnym requescie wysylac nasz token ktory jest w cookiesach w celu sprawdzenia go w backendzie. Jedyna kwestia jaka mnie zastanawia, to taka, jak mam umiescic ten jwt token, aby go sprawdzac do kazdego requesty i identyfikowac z danym userem (zeby np. pozniej pobierac dane z zalogowanego usera).

Generalnie w jwt jest sekcja payload, gdzie mozemy wstawic id naszego usera oraz zalozmy login, wszystko spoko, tylko ze do czego mam pozniej sie odwolywac, zeby w kazdym requescie znalezc tego usera + jego token do autoryzacji. Myslalem po prostu nad tym aby nadzwyczajniej walnac to do sesji i sprawdzac w sesyjnej tablicy czy sie zgadza token, jak sie zgadza to wykonyc operacje na sesji['id'] usera np. Dobry pomysl?

1 użytkowników online, w tym zalogowanych: 0, gości: 1