Użytkownicy i przywileje Sesja - przykład Błędy Komunikacja międzyskryptowa Wykład 83PD Technologie internetowe
MySQL rozróżnia cztery poziomy przywilejów użytkowników. Dane zapisywane są w bazie mysql w odpowiednich tabelach
poziom globalny (tabela user) – dostęp do wszystkich baz, poziom bazy danych (tabela db) – dostęp do wybranych baz poziom tabel (tabela tables_priv) – dostęp do wybranych tabel bazy, poziom pól (tabela columns_priv) – dostęp do wybranych pól tabeli bazy.
Polecenie GRANT nadawanie przywilejów GRANT lista_przywilejów [lista_pól] ON baza. tabela TO IDENTIFIED BY 'haslo' WITH GRANT OPTION;
GRANT USAGE ON ksiegarnia.ksiazki TO uzytkownik IDENTIFIED BY 'abc11'; Przykładowo:
Lista przywilejów: PrzywilejOpis USAGE Nie nadaje żadnych przywilej ó w ALL albo ALL PRIVILEGES Nadaje wszystkie przywileje SELECTPozwala na wyszukiwanie INSERTPozwala na wstawianie wierszy do tabel UPDATE Pozwala na zmianę wartości p ó l DELETE Pozwala na usuwanie rekord ó w
INDEX Pozwala na tworzenie i usuwanie indeks ó w ALTERPozwala na dokonywanie zmian w strukturze tabel, nazw i typ ó w CREATEPozwala na tworzenie baz i tabel DROPPozwala na usuwanie baz i tabel GRANTPozwala na nadawanie przywilejów innym – tylko przez GRANT OPTION
Polecenie REVOKE służy do odbierania przywilejów. Składnia ogólna to: REVOKE przywileje ON obiekt FROM nazwa_użytkownika; REVOKE update, select ON ksiazki FROM b; np.: Polecenie REVOKE
Przykłady: GRANT USAGE ON * to a;{bez hasła) GRANT USAGE ON * to a identified by 'a'; GRANT SELECT ON * to b identified by 'b'; REVOKE UPDATE, SELECT ON ksiazki FROM b;
ALBO... INSERT INTO user SET host='%', user='n1', password ='alfa123'; INSERT INTO user SET host='%', user='n2', password =password('6789'); {szyfrowanie hasła}
Ale wpisy do tabel bazy MYSQL po podaniu polecenia: mysql> FLUSH PRIVILEGES;
Polecenie SHOW GRANTS Sprawdzenie przywilejów np. SHOW GRANTS FOR root;
Przekazywanie danych między plikami Metody: -zapis i odczyt z pliku na serwerze -umieszczenie w COOKIE po stronie klienta -zapis i odczyt z bazy danych -umieszczenie w tablicy _SESSION -przekaz danych roboczych metodami GET i POST (formularz i hiperłącze)
<?php session_start(); ?> <?php $_SESSION['a']=1; //umieszczenie danych w sesji $_SESSION['b']=3; print_r($_SESSION); echo " "; echo "Oto zmienne sesji:"; print_r($_SESSION); echo " a=".$_SESSION['a']; echo " "; echo "b=".$_SESSION['b']; echo " "; echo " DRUGI "; ?> Przykłady sesji Zawsze przed wysłaniem nagłówków!
<?php session_start(); echo "Oto zmienne sesyjne:"; print_r($_SESSION); echo " a=".$_SESSION['a']; echo " Wyrejestrowanie zmiennej "; unset ($_SESSION['a']); echo " Zmienne sesyjne po wyrejestrowaniu zmiennej a: "; print_r($_SESSION); session_unset(); //session_unregister zdeprecjonowane w nowych PHP //można też …unset($_SESSION); echo " Zmienne sesyjne po usunięciu sesji: "; print_r($_SESSION); if (isset($a)) echo " a=".$a; else echo " Nie istnieje tez jako zmienna globalna "; echo " Ponowna rejestracja a=100 "; $_SESSION['a']=100; echo " TRZECI "; ?> drugi.php
<?php session_start(); echo "Oto zmienne sesyjne:"; print_r($_SESSION); if (isset($_SESSION['a'])) echo " zmienna 'a' JEST w sesji"; else echo " 'a' NIE MA w sesji"; if (isset($_SESSION['b'])) echo " zmienna 'b' JEST w sesji"; else echo " 'b' NIE MA w sesji"; ?> trzeci.php
Formularz – tablice $_POST lub $_GET <?php $x1=100; $x2=200; ?> POST ze skryptami PHP wstawiającym wartość zmiennej x1 a x2 przez ukryte pole "> plik wynik_form.php <?php echo $_POST["pierwsza"]; echo $_POST["druga"]; ?>
<?php $x1=100;$x2=50; echo " Hiperłącze bez argumentu w PHP "; echo " Hiperłącze z argumentem – metoda GET - w PHP "; // można przekazać wiele wartości..?x1=$x1&x2=$x2... ?> plik wynik_hip.php <?php echo $_GET["x1"]; echo $_GET["x2"]; itd.. ?> Hiperłącze
Przekazanie tablicy przez metodę GET dla URL <?php $x1=array(1.1, 2.2, 3.3, 4.4, 123); $x1=serialize($x1); echo " Wykonaj "; ?> <?php $y=unserialize($_GET['x1']); for ($i=0;$i<5;$i++) echo "$y[$i] "; ?>
Problemy i kłopoty….. Uniemożliwienie zakupu ostatniego zapasu dwóch klientów widzi dostępność ostatniego egzemplarza obaj decydują się na zakup Uniemożliwienie podwójnego uzupełniania zapasów przez administratorów Problemy współbieżności Dostęp przez wielu użytkowników (też administratorów) Jednorodność ciągu operacji - transakcja
Zapewnia, że przerwanie wykonania ciągu operacji (przez błąd lub awarię) nie spowoduje utraty spójności bazy danych. System zarządzania bazą danych (SZDB) winien przywrócić bazę do stanu sprzed startu transakcji. Mechanizm transakcji Przykład: Przelew bankowy – operacje elementarne: 1.Odjęcie z konta A 2.Dodanie do konta B MySQL nie posiada mechanizmów obsługi transakcji, trzeba je samodzielnie oprogramować
Zagubiona aktualizacja użytkownik A – odczyt użytkownik B – aktualizacja A – aktualizacja (zmiana tego co zrobił B) Brudny odczyt A – aktualizacja B – aktualizacja A – cofnięcie aktualizacji (niemożliwe bo już inne dane) Błędne podsumowanie A – aktualizacja B – czytanie i sumowanie (błędy) Niepowtarzalny odczyt A – odczyt B – aktualizacja A – ponowny odczyt w celu weryfikacji (dwie wartości) Ratunek -> blokowanie tabel (aż do ostatecznej akceptacji) Przyczyny błędów
..... // potrzebny formularz do wpisania nr_kl $QUERY= " LOCK TABLES pozycje READ, sprzedaz WRITE, klienci READ"; …. //zapytanie SELECT dla wszystkich tabel $zap1="SELECT sum(cena*ilosc) FROM pozycje, sprzedaz, klienci WHERE klienci.id_kl=sprzedaz.id_kl AND sprzedaz.id_zam=pozycje.id_zam AND klienci.Id_kl=".$_POST['nr_kl']; $wynik=mysql_query($zap1,$polaczenie); $wiersz =mysql_fetch_array($wynik); //zapytanie UPDATE dla tabeli SPRZEDAZ if ($wiersz[SUM(cena*ilosc)]>$minimum) { $zap2="UPDATE sprzedaz SET upust=10 WHERE Id_kl=".$nr_kl; $wynik2=mysql_query($zap2,$polaczenie); } $QUERY = " UNLOCK TABLES" ; Przykład: Uwzględnienie upustu
Skrypty kombinowane – html+php Niebezpieczeństwo dwukrotnego dodania tego samego wiersza w tabeli w przypadku: RELOAD – Odśwież w przeglądarce BACK – Wstecz lub FORWARD - Dalej Wybór ponowny z Ulubionych (zakładek) Jeśli UPDATE to nie ma niebezpieczeństwa (najwyżej błąd MySQL) Jak temu zaradzić? Używanie metody POST – mniej podatna na problem odświeżania Używanie funkcji nagłówkowej header – wymuszenie przekazania do innego pliku Problem odświeżania
Prawidłowo 2 skrypty: index.php <?php $connection=mysql_connect('localhost','root',''); mysql_select_db('hurtownia'); echo $query= "INSERT INTO klienci VALUES (null,'c','c','','','','','','','','','','c')"; if ($query, $connection))&& mysql_affected_rows() == 1) header("Location: potw.php?Id_kl=".mysql_insert_id($connection)."&status=T"); else header ("Location: potw.php?"."status=F"); ?> mysql_insert_id (polaczenie) – znajduje wartość klucza podstawowego dla dopisanego rekordu,, o ile wstawiono 1 rekord o kluczu typu AUTO_INCREMENT
skrypt potw.php Potwierdzenie <?php $status=$_GET['status'] " ; echo " Id_kl= " $_GET['Id_kl'] ; switch ($status) { case "T": echo "TAK"; break; case "F": echo "NIE"; break; default: echo "Nie wiadomo co się stało"; } ?>