Witam.
postanowiłem napisać logowanie opartym o jquery i teraz się zastanawiam czy to będzie dobry pomysł pod względem bezpieczeństwa.
php:
/*Funkcja zapisująca ciasteczka */ function docookie($setuid, $setusername) { $info = http://www.php.net/base64_encode("$setuid:$setusername"); http://www.php.net/setcookie("user","$info",http://www.php.net/time()+3600); return $info; } $user = $_GET['Username']; $password = http://www.php.net/trim($_GET['Password']); $query = $pdo->prepare("SELECT `user`, `password`, `pass_pass`, `id_user` FROM `users` WHERE `user` = :user AND `password` = :password LIMIT 1"); $query->bindValue(':user', $user, PDO::PARAM_STR); $query->bindValue(':password', SafePassword($password), PDO::PARAM_STR); $query->execute(); $fetch = $query->fetch(); if(http://www.php.net/empty($user)){ $status = "error"; $message = "".LANG_AJAX_LOGIN_NIEPODANO."."; }elseif(!http://www.php.net/is_array($fetch)){ $status = "error"; $message = ''.LANG_AJAX_LOGIN_NIEMA.'.'; }elseif(http://www.php.net/empty($password)){ $status = "error"; $message = "".LANG_AJAX_HASLO_NIEPODANO."."; }else{ http://www.php.net/mt_srand ((double)http://www.php.net/microtime()*1000000); $maxran = 1000000; $random_num = http://www.php.net/mt_rand(0, $maxran); $datekey = http://www.php.net/date("F j"); $rcode = http://www.php.net/hexdec(http://www.php.net/md5($_SERVER['HTTP_USER_AGENT'] . $random_num . $datekey)); $code = http://www.php.net/substr($rcode, 2, 6); docookie($fetch['id_user'], $user); $status = "success"; $message = 'Zalogowano poprawnie.'.$code; }
var SignIn = function() { $('#LoginButton,#LoginButtonTop').on('click', function (){ var form = $('#login').serialize(), responseMsg = $('#messageLogin,#messageLoginTop'); responseMsg.hide().addClass('response-waiting').text('czekaj...').fadeIn(200); $.ajax({ type: 'GET', url: "/ajax.php?p=login", data: form, processData: false, contentType: false, success: function(data){ var responseData = jQuery.parseJSON(data), klass = ''; switch(responseData.status){ case 'error': klass = 'response-error'; break; case 'success': klass = 'response-success'; break; } responseMsg.fadeOut(200,function(){ $(this).removeClass('response-waiting').addClass(klass).html(responseData.message).fadeIn(200,function(){ if(responseData.status == 'error'){ setTimeout(function(){ responseMsg.fadeOut(200,function(){ $(this).removeClass(klass); }); },3000); }else { setTimeout('go_to_private_page()', 3000); } }); }); } }); return false; }); }
Czemu nie używasz password_hash i verify dla haseł?
Po to tu napisałem by otrzymać pomoc
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 ?
Zobacz w dokumentacji. Do jquery i kodu js dostęp ma każdy więc to by była jedna z głupszych rzeczy.
wcześniej kodowane hasło miałem za pomocą:
function SafePassword($password) { return openssl_digest($password, 'sha512'); } $query->bindValue(':password', SafePassword($password), PDO::PARAM_STR);
$passwordPlain = 'pass123'; $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT); password_verify($passwordPlain, $passwordHash);
function SafePassword($password, $passwordTwo) { return password_verify($password, $passwordTwo); }
password_hash($password, PASSWORD_BCRYPT);
Od 7.2 algorytmem jest argon2i. Funkcja safepassword w tym wypadku nic nie robi.
nie bardzo wiem jak to teraz ugryźć, bo przy zapisie do bazy:
function SafePassword($password) { return password_hash($password); } $AddUser->bindValue(':password', SafePassword($password), PDO::PARAM_STR);
if(http://www.php.net/empty($user)){ $status = "error"; $message = "".LANG_AJAX_LOGIN_NIEPODANO."."; }elseif(!http://www.php.net/is_array($fetch)){ $status = "error"; $message = ''.LANG_AJAX_LOGIN_NIEMA.''; }elseif(http://www.php.net/empty($password)){ $status = "error"; $message = "".LANG_AJAX_HASLO_NIEPODANO."."; }else{ http://www.php.net/echo ' zalogowano'; }
Przy zapisie do bazy hash a potem wyciągasz użytkownika na podstawie loginu i porównujesz verify hasło podane z hashem.
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
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.
https://stackoverflow.com/questions/14612551/mysql-remote-connection-fails-with-unknown-authentication-method
@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:
$query = $pdo->prepare("SELECT `user`, `password`, `pass_pass`, `id_user` FROM `users` WHERE `user` = :user LIMIT 1"); $query->bindValue(':user', $user, PDO::PARAM_STR); $query->execute(); $row = $query->fetch(PDO::FETCH_ASSOC); if(http://www.php.net/empty($user)){ $status = "error"; $message = "".LANG_AJAX_LOGIN_NIEPODANO."."; }elseif(http://www.php.net/empty($password)){ $status = "error"; $message = "".LANG_AJAX_HASLO_NIEPODANO."."; }elseif($row){ if(password_verify($password,$row['password'])){ http://www.php.net/mt_srand ((double)http://www.php.net/microtime()*1000000); $maxran = 1000000; $random_num = http://www.php.net/mt_rand(0, $maxran); $datekey = http://www.php.net/date("F j"); $rcode = http://www.php.net/hexdec(http://www.php.net/md5($_SERVER['HTTP_USER_AGENT'] . $random_num . $sitekey . $datekey)); $code = http://www.php.net/substr($rcode, 2, 6); $status = "success"; $message = 'Zalogowano poprawnie.'.$code; }else{ $status = "error"; $message = ''.LANG_AJAX_LOGIN_NIEMA.''; } }
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?
na froncie powinieneś mieć coś takiego
success: function (response) { // jak wyślesz kod odpowiedzi 200 to się wykona ten blok // po pytaniach wątpię, że robisz SPA, dlatego możesz zrobić refresh dla strony i wyświetli się widok dla zalogowanego }, error: function (xhr, ajaxOptions, thrownError) { // w przypadku errorów walidacji wysyłaj kod 400, // wtedy wykona się zawartość tej funkcji // mozesz rozróżnic kod odpowiedzi, w przypadku 500 pokazuj inną informację }
@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" ?
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...
No dobra czyli w efekcie końcowym ma być tak:
var SignIn = function() { $('#LoginButton,#LoginButtonTop').on('click', function (){ var form = $('#login').serialize(), responseMsg = $('#messageLogin,#messageLoginTop'); responseMsg.hide().addClass('response-waiting').text('czekaj...').fadeIn(200); $.ajax({ type: 'GET', url: "/ajax.php?p=login", data: form, processData: false, contentType: false, success: function(data, textStatus, jQxhr) { var responseData = jQuery.parseJSON(data), klass = ''; switch(responseData.status){ case 'error': klass = 'response-error'; break; case 'success': klass = 'response-success'; break; } responseMsg.fadeOut(200,function(){ $(this).removeClass('response-waiting').addClass(klass).html(responseData.message).fadeIn(200,function(){ if(responseData.status == 'error'){ setTimeout(function(){ responseMsg.fadeOut(200,function(){ $(this).removeClass(klass); }); },3000); } if(responseData.status == 'success'){ var url4 = window.location.href; setTimeout(function() { window.location.reload(url4); location.reload(true); }, 1000); /*automatyczne odświeżenie strony */ } }); }); }, complete: function() { //ten fragment wykona się po zakończeniu łączenia - nie ważne czy wystąpił błąd, czy sukces }, error: function(jqXHR, errorText, errorThrown) { console.log( errorThrown ); } }); return false; }); }
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?
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_przygotowac_php_do_obslugi_zadan_xhr_json%3F
@nospor SignIn poprawiony na signIn
to:
if(responseData.status == 'error'){ setTimeout(function(){ responseMsg.fadeOut(200,function(){ $(this).removeClass(klass); }); },3000); }
To nazwij to np. messageClass tylko na jadro linuksa nie spolszaczaj tego w ten sposob
@viking fail() / done() jest w nowszej wersji jQuery , nie chce teraz ruszać strony by się nie posypała
@nospor usunąłem switcha i (c/k)lass
czy teraz wygląda Panowie kod optymalnie , nie czepiając się oczywiście nowego jQuery.
obecny JS wygląda tak:
var signIn = function() { $('#LoginButton,#LoginButtonTop').on('click', function (){ var form = $('#login').serialize(), responseMsg = $('#messageLogin,#messageLoginTop'); responseMsg.hide().addClass('response-waiting').text('czekaj...').fadeIn(200); $.ajax({ type: 'GET', url: "/ajax.php?p=login", data: form, dataType: 'json', success: function(data, textStatus, jQxhr) { responseMsg.fadeOut(200,function(){ $(this).removeClass('response-waiting').addClass('response-success').html(data.message).fadeIn(200,function(){ var url4 = window.location.href; setTimeout(function() { window.location.reload(url4); location.reload(true); }, 1000); /*automatyczne odświeżenie strony */ }); }); }, complete: function() { //ten fragment wykona się po zakończeniu łączenia - nie ważne czy wystąpił błąd, czy sukces }, error: function(jqXHR, errorText, errorThrown) { console.log( errorThrown ); responseMsg.fadeOut(200,function(){ $(this).removeClass('response-waiting').addClass('response-error').html(jqXHR.responseJSON.message).fadeIn(200,function(){ setTimeout(function(){ responseMsg.fadeOut(200,function(){ $(this).removeClass('response-error'); }); },3000); }); }); } }); return false; }); }
http://www.php.net/echo json_encode(['message' => 'wiadomość przekaż']); return;
.fail(function(jqXHR, errorText, errorThrown) { console.log( errorThrown ); $(this).html(jqXHR.responseJSON.message); }); return false;
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)