Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> [PHP]AJAX logowanie, pomoc w zabezpieczeniu kodu
casperii
post 7.10.2018, 10:56:46
Post #1





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


Witam.
postanowiłem napisać logowanie opartym o jquery i teraz się zastanawiam czy to będzie dobry pomysł pod względem bezpieczeństwa.

php:
  1. /*Funkcja zapisująca ciasteczka */
  2. function docookie($setuid, $setusername) {
  3. $info = base64_encode("$setuid:$setusername");
  4. setcookie("user","$info",time()+3600);
  5. return $info;
  6. }
  7.  
  8.  
  9. $user = $_GET['Username'];
  10. $password = trim($_GET['Password']);
  11.  
  12. $query = $pdo->prepare("SELECT `user`, `password`, `pass_pass`, `id_user` FROM `users` WHERE `user` = :user AND `password` = :password LIMIT 1");
  13. $query->bindValue(':user', $user, PDO::PARAM_STR);
  14. $query->bindValue(':password', SafePassword($password), PDO::PARAM_STR);
  15.  
  16. $query->execute();
  17. $fetch = $query->fetch();
  18.  
  19. if(empty($user)){
  20. $status = "error";
  21. $message = "".LANG_AJAX_LOGIN_NIEPODANO.".";
  22. }elseif(!is_array($fetch)){
  23. $status = "error";
  24. $message = ''.LANG_AJAX_LOGIN_NIEMA.'.';
  25. }elseif(empty($password)){
  26. $status = "error";
  27. $message = "".LANG_AJAX_HASLO_NIEPODANO.".";
  28. }else{
  29.  
  30. mt_srand ((double)microtime()*1000000);
  31. $maxran = 1000000;
  32. $random_num = mt_rand(0, $maxran);
  33.  
  34.  
  35. $datekey = date("F j");
  36. $rcode = hexdec(md5($_SERVER['HTTP_USER_AGENT'] . $random_num . $datekey));
  37. $code = substr($rcode, 2, 6);
  38.  
  39. docookie($fetch['id_user'], $user);
  40.  
  41. $status = "success";
  42. $message = 'Zalogowano poprawnie.'.$code;
  43. }


JS:

  1. var SignIn = function() {
  2. $('#LoginButton,#LoginButtonTop').on('click', function (){
  3. var form = $('#login').serialize(),
  4. responseMsg = $('#messageLogin,#messageLoginTop');
  5. responseMsg.hide().addClass('response-waiting').text('czekaj...').fadeIn(200);
  6.  
  7. $.ajax({
  8. type: 'GET',
  9. url: "/ajax.php?p=login",
  10. data: form,
  11. processData: false,
  12. contentType: false,
  13. success: function(data){
  14. var responseData = jQuery.parseJSON(data),
  15. klass = '';
  16. switch(responseData.status){
  17. case 'error':
  18. klass = 'response-error';
  19. break;
  20.  
  21. case 'success':
  22. klass = 'response-success';
  23. break;
  24. }
  25.  
  26. responseMsg.fadeOut(200,function(){
  27. $(this).removeClass('response-waiting').addClass(klass).html(responseData.message).fadeIn(200,function(){
  28.  
  29. if(responseData.status == 'error'){
  30. setTimeout(function(){
  31. responseMsg.fadeOut(200,function(){
  32. $(this).removeClass(klass);
  33. });
  34. },3000);
  35.  
  36. }else { setTimeout('go_to_private_page()', 3000); }
  37.  
  38.  
  39. });
  40. });
  41. }
  42. });
  43. return false;
  44. });
  45. }
Go to the top of the page
+Quote Post
viking
post 7.10.2018, 11:37:20
Post #2





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Czemu nie używasz password_hash i verify dla haseł?


--------------------
Go to the top of the page
+Quote Post
casperii
post 7.10.2018, 11:52:55
Post #3





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


Po to tu napisałem by otrzymać pomoc smile.gif
Jak już wspomniałeś o:
password_hash i verify

możesz coś więcej nadmienić jak to powinno wyglądać ? hashuje hasło w jquery i przesyłaniu do php i tam je odkodowuje ? czy o co chodzi ?
Go to the top of the page
+Quote Post
viking
post 7.10.2018, 11:57:58
Post #4





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Zobacz w dokumentacji. Do jquery i kodu js dostęp ma każdy więc to by była jedna z głupszych rzeczy.


--------------------
Go to the top of the page
+Quote Post
casperii
post 7.10.2018, 12:07:40
Post #5





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


wcześniej kodowane hasło miałem za pomocą:

  1. function SafePassword($password) {
  2. return openssl_digest($password, 'sha512');
  3. }
  4. $query->bindValue(':password', SafePassword($password), PDO::PARAM_STR);


dobra kumam, trzeba iść z biegiem wyższego Php'a:
  1. $passwordPlain = 'pass123';
  2. $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT);
  3. password_verify($passwordPlain, $passwordHash);


czyli:
  1. function SafePassword($password, $passwordTwo) {
  2. return password_verify($password, $passwordTwo);
  3. }


a przy zapisie / rejestracji usera
  1. password_hash($password, PASSWORD_BCRYPT);


czyli reasumując user wpisuje swój login muszę najpierw zwrócić hasło by później je wstawić do funkcji i porównać czy jest true czy false ?
Go to the top of the page
+Quote Post
viking
post 7.10.2018, 12:14:59
Post #6





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Od 7.2 algorytmem jest argon2i. Funkcja safepassword w tym wypadku nic nie robi.


--------------------
Go to the top of the page
+Quote Post
casperii
post 7.10.2018, 12:32:37
Post #7





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


nie bardzo wiem jak to teraz ugryźć, bo przy zapisie do bazy:

  1. function SafePassword($password) {
  2. return password_hash($password);
  3. }
  4.  
  5. $AddUser->bindValue(':password', SafePassword($password), PDO::PARAM_STR);


tak przy porównywaniu już na etapie bindowania mam te hasło porównywać czy najpierw te hasło wprowadzone hasło przelecieć raz jeszcze function SafePasswrod?smile.gif

a później w warunku sprawdzić ?

  1. if(empty($user)){
  2. $status = "error";
  3. $message = "".LANG_AJAX_LOGIN_NIEPODANO.".";
  4. }elseif(!is_array($fetch)){
  5. $status = "error";
  6. $message = ''.LANG_AJAX_LOGIN_NIEMA.'';
  7. }elseif(empty($password)){
  8. $status = "error";
  9. $message = "".LANG_AJAX_HASLO_NIEPODANO.".";
  10. }else{
  11. echo ' zalogowano';
  12.  
  13. }


Go to the top of the page
+Quote Post
viking
post 7.10.2018, 12:39:28
Post #8





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Przy zapisie do bazy hash a potem wyciągasz użytkownika na podstawie loginu i porównujesz verify hasło podane z hashem.


--------------------
Go to the top of the page
+Quote Post
casperii
post 7.10.2018, 12:41:02
Post #9





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


oł patrz na to: Call to undefined function password_hash()

a tu zonk:
PHP Version 5.3.29
a w/w działa od 5.5

Ten post edytował casperii 7.10.2018, 12:51:17
Go to the top of the page
+Quote Post
viking
post 7.10.2018, 13:22:02
Post #10





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


No to najwyższa pora zmienić hosting bo nawet na takim starociu nie ma powodu żeby rozmawiać o "bezpieczeństwie". Od lat nie ma wsparcia ani łat.


--------------------
Go to the top of the page
+Quote Post
woxala123
post 7.10.2018, 18:00:37
Post #11





Grupa: Zarejestrowani
Postów: 361
Pomógł: 12
Dołączył: 9.01.2010

Ostrzeżenie: (10%)
X----


https://stackoverflow.com/questions/1461255...tication-method
Go to the top of the page
+Quote Post
casperii
post 7.10.2018, 23:26:42
Post #12





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


@woxala123 tak na przyszłość nie podawaj linków , które nic nie wnoszą , tym bardziej u kogoś kto potrzebuje pomocy.
Temat z błędem mysql rozwiązany, wystarczyło usunąć usera i utworzyć ponownie oraz połączyć go z bazą danych.

ostateczny php:

  1. $query = $pdo->prepare("SELECT `user`, `password`, `pass_pass`, `id_user` FROM `users` WHERE `user` = :user LIMIT 1");
  2. $query->bindValue(':user', $user, PDO::PARAM_STR);
  3.  
  4. $query->execute();
  5. $row = $query->fetch(PDO::FETCH_ASSOC);
  6.  
  7. if(empty($user)){
  8. $status = "error";
  9. $message = "".LANG_AJAX_LOGIN_NIEPODANO.".";
  10. }elseif(empty($password)){
  11. $status = "error";
  12. $message = "".LANG_AJAX_HASLO_NIEPODANO.".";
  13. }elseif($row){
  14. if(password_verify($password,$row['password'])){
  15.  
  16. mt_srand ((double)microtime()*1000000);
  17. $maxran = 1000000;
  18. $random_num = mt_rand(0, $maxran);
  19.  
  20. $datekey = date("F j");
  21. $rcode = hexdec(md5($_SERVER['HTTP_USER_AGENT'] . $random_num . $sitekey . $datekey));
  22. $code = substr($rcode, 2, 6);
  23.  
  24. $status = "success";
  25. $message = 'Zalogowano poprawnie.'.$code;
  26. }else{
  27. $status = "error";
  28. $message = ''.LANG_AJAX_LOGIN_NIEMA.'';
  29. }
  30.  
  31. }


teraz pytanie co powinienem przekazać do jquery żeby zalogować i żeby nie można było tego wyłudzić ?
wymyśliłem sobie, że tworząc $code będzie można go przekazać i w jquery sprawdzać jego poprawność ale nie wiem czy to nie przekombinowane ?
Go to the top of the page
+Quote Post
nospor
post 8.10.2018, 09:56:16
Post #13





Grupa: Moderatorzy
Postów: 36 440
Pomógł: 6290
Dołączył: 27.12.2004




Nie bardzo rozumiem po co chcesz jakies info przekazywac do jQuery? Zalogowanie zrobiles w php i user jest zalogowany. Co ma ci ktos wyludzac w jquery?


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
borabora
post 8.10.2018, 10:22:11
Post #14





Grupa: Zarejestrowani
Postów: 116
Pomógł: 33
Dołączył: 8.09.2014

Ostrzeżenie: (0%)
-----


na froncie powinieneś mieć coś takiego
  1. success: function (response) {
  2. // jak wyślesz kod odpowiedzi 200 to się wykona ten blok
  3. // po pytaniach wątpię, że robisz SPA, dlatego możesz zrobić refresh dla strony i wyświetli się widok dla zalogowanego
  4. },
  5. error: function (xhr, ajaxOptions, thrownError) {
  6. // w przypadku errorów walidacji wysyłaj kod 400,
  7. // wtedy wykona się zawartość tej funkcji
  8. // mozesz rozróżnic kod odpowiedzi, w przypadku 500 pokazuj inną informację
  9. }
Go to the top of the page
+Quote Post
viking
post 8.10.2018, 11:04:38
Post #15





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Kod
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are removed as of jQuery 3.0. You can use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.


--------------------
Go to the top of the page
+Quote Post
casperii
post 8.10.2018, 20:35:23
Post #16





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


@borabora , @viking a to nie jest tak , że success() , error() zostało zastąpione done() , fail()
@borabora możesz wyjaśnić o co chodziło czy robię "SPA" ?
Go to the top of the page
+Quote Post
borabora
post 9.10.2018, 15:07:55
Post #17





Grupa: Zarejestrowani
Postów: 116
Pomógł: 33
Dołączył: 8.09.2014

Ostrzeżenie: (0%)
-----


SPA - single page application. Czyli "cały" front ładuje się raz, a następnie po logowaniu dostajesz obiekt (token, nick, avatar...). Wtedy zmieniasz stan z wylogowanego na zalogowany. Dłuższy temat...
Go to the top of the page
+Quote Post
casperii
post 10.10.2018, 20:12:46
Post #18





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


No dobra czyli w efekcie końcowym ma być tak:

  1. var SignIn = function() {
  2. $('#LoginButton,#LoginButtonTop').on('click', function (){
  3. var form = $('#login').serialize(),
  4. responseMsg = $('#messageLogin,#messageLoginTop');
  5. responseMsg.hide().addClass('response-waiting').text('czekaj...').fadeIn(200);
  6.  
  7. $.ajax({
  8. type: 'GET',
  9. url: "/ajax.php?p=login",
  10. data: form,
  11. processData: false,
  12. contentType: false,
  13.  
  14. success: function(data, textStatus, jQxhr) {
  15. var responseData = jQuery.parseJSON(data),
  16. klass = '';
  17. switch(responseData.status){
  18. case 'error':
  19. klass = 'response-error';
  20. break;
  21.  
  22. case 'success':
  23. klass = 'response-success';
  24. break;
  25. }
  26.  
  27. responseMsg.fadeOut(200,function(){
  28. $(this).removeClass('response-waiting').addClass(klass).html(responseData.message).fadeIn(200,function(){
  29.  
  30. if(responseData.status == 'error'){
  31. setTimeout(function(){
  32. responseMsg.fadeOut(200,function(){
  33. $(this).removeClass(klass);
  34. });
  35. },3000);
  36.  
  37. }
  38.  
  39. if(responseData.status == 'success'){
  40. var url4 = window.location.href;
  41. setTimeout(function() {
  42. window.location.reload(url4);
  43. location.reload(true);
  44. }, 1000); /*automatyczne odświeżenie strony */
  45. }
  46.  
  47. });
  48. });
  49.  
  50. },
  51. complete: function() {
  52. //ten fragment wykona się po zakończeniu łączenia - nie ważne czy wystąpił błąd, czy sukces
  53. },
  54. error: function(jqXHR, errorText, errorThrown) {
  55. console.log( errorThrown );
  56. }
  57. });
  58.  
  59. return false;
  60.  
  61. });
  62. }


ktoś rzucił by fachowym okiem i wyeliminował nie potrzebne fragmenty ? smile.gif
Go to the top of the page
+Quote Post
nospor
post 10.10.2018, 20:50:44
Post #19





Grupa: Moderatorzy
Postów: 36 440
Pomógł: 6290
Dołączył: 27.12.2004




Z takich pierdow ale az klujacych w oczy

nie: klass
a: class

Nie: SignIn
a: signIn - trzymaj sie jednej konwencji a nie wolna amerykanka

No i czemu jak jest blad to pojazujesz go dopiero po 3 sekundach? Po co bez sensu zwlekac?
No i czemu jak jest ok to przekierowujesz dopiero po jednej sekundzie? przeciez nie robisz nic w miedzyczasie. I znowu pytanie: po co wiec zwlekac?


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
viking
post 11.10.2018, 06:42:43
Post #20





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


I nie zastosowałeś done/fail tylko usunięte succes/error. Dodatkowo bezsensowne przetwarzanie success switchem zamiast wysłanie odpowiedniego błędu. Dlaczego contentType: false?
https://prophp.pl/advice/show/17/jak_przygo...dan_xhr_json%3F


--------------------
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 29.03.2024 - 13:10