Autor Zpráva
soucekgns
Profil
Rád bych se zeptal jaký je váš názor na moje přihlašování, kde je potenciální chyba a co lze zlepšit nebo udělat jinak.
Kód na manuální odhlášení jsem ještě neřešil, ale když ho budu vytvářet, má smysl přepisovat i údaje v mysql nebo stačí jen smazat cookies?

MYSQL:
id=user; time="čas přihlášení"+1 hodina; user="přihlašovací jméno"; value="md5 heslo"; token="náhodně generované číslo"; ip="uživatelova ip"
<?php
  $v->login = false;
  $v->user_ip = $_SERVER['REMOTE_ADDR'];

  if (isset($_POST["f_login_send"])) {
    // Get sent values
    $v->user_name = $mysqli->real_escape_string($_POST["f_login_name"]); 
    $v->user_pass = md5($mysqli->real_escape_string($_POST["f_login_pass"]));
    $v->user_token = md5(uniqid(mt_rand(), true));

    // Search database for name and password
    $query = "SELECT * FROM settings WHERE id='user' AND user='".$v->user_name."' AND value='".$v->user_pass."'";
    if ($mysqli->query($query)) {
      // If it finds exactly one record
      if ($mysqli->affected_rows == 1) {
        // Update token, IP and time
        $update_query = "UPDATE settings SET token='".$v->user_token."', ip='".$v->user_ip."', time='".date("Y-m-d H:i:s", time()+60*60)."' WHERE id='user' AND user='".$v->user_name."' AND value='".$v->user_pass."'";
        if ($mysqli->query($update_query)) {
          // If everything OK, set cookies and open up the content 
          setcookie("UID", $v->user_name, 0);
          setcookie("TOKEN", $v->user_token, 0);
          $v->login = true;
          $m->login_as = "Přihlášen jako ".$v->user_name.", odhlásíte se zavřením prohlížeče.";
        }
        else $m->login_update_error = "Chyba v ukládání dat do databáze.";
      }
      else $m->login_incorrect = "Špatné jméno nebo hleslo.";
    }
  }

  // If cookie exists
  if (isset($_COOKIE["UID"]) AND isset($_COOKIE["TOKEN"])) {
    $v->cookie_user = $mysqli->real_escape_string($_COOKIE["UID"]);
    $v->cookie_token = $mysqli->real_escape_string($_COOKIE["TOKEN"]);

    // Search database if the cookies and ip are the same and if the time value isn't expired
    $query = "SELECT * FROM settings WHERE id='user' AND user='".$v->cookie_user."' AND token='".$v->cookie_token."' AND ip='".$v->user_ip."' AND time>'".date("Y-m-d H:i:s")."'";
    if ($result = $mysqli->query($query)) {
      // If it finds exactly one record
      if ($mysqli->affected_rows == 1) $v->login = true;
      $result->free();
    }

    // If there are wrong cookie values, delete them
    if ($v->login == false) {
      setcookie("UID", "", 1);
      setcookie("TOKEN", "", 1);
      $m->login_expired = "Byl proveden pokus o neautorizované přihlášení nebo již vypršel čas. Přihlaste se znovu.";
    }
  }
?>
Alphard
Profil
IP bych nekontroloval, když se vám mění každých pár kroků a pořád vás systém odhlašuje, je to na zabití. Maximálně pro kritické systémy jako bankovnictví apod.
Jan Tvrdík
Profil
soucekgns:
1) MD5 je velmi nedostatečná funkce pro hashování hesel. Použij funkci crypt s blowfish hashováním nebo funkce password_hash a password_verify dostupné od PHP 5.5 (pro starší verze lze použít knihovnu password_compat).

2) Generovaný token imho není kryptograficky bezpečný a lze ho tedy uhádnout. Viz www.slideshare.net/DefconRussia/reutov-yunusov-nagibin-random-numbers-take-ii a github.com/nette/nette/pull/882. Bezpečný token umí vygenerovat např. funkce openssl_random_pseudo_bytes.

3) Proč vlastně nepoužiješ sessions?
Camo
Profil
soucekgns:
Výsledok hašovacích funkcií ako md5 je hexadecimálne číslo, takže ho netreba escapovať.
soucekgns
Profil
Alphard:
Je to psané jako interní systém pro počítače (ne mobily), něco jako sednu si doma a stáhnu si info. A tím že se tam musí přihlašovat každou session, tak to ani neovlivní:)

Jan Tvrdík:
Díky, kouknu se na to.
3) Proč vlastně nepoužiješ sessions?
Přemýšlel jsem o tom, ale asi to ještě upravím a nějaký ten čas tam nastavím, aby trvalo automatické přihlášení třeba celý večer.

Camo:
Jo, jak jsem to kopíroval, tak jsem si to ani neuvědomil:)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: