Aprenda a construir um sistema de login em PHP com password_hash/password_verify, sessões seguras, proteção CSRF e logout. Os exemplos usam PDO e prepared statements para evitar SQL Injection.
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(191) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
Dica: use utf8mb4 no banco, email unique e índices conforme necessidade.
<?php
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '',
'secure' => isset($_SERVER['HTTPS']),
'httponly' => true,
'samesite' => 'Lax'
]);
session_start();
session_regenerate_id(true);
<?php
$pdo = new PDO('mysql:host=localhost;dbname=app;charset=utf8mb4', 'user', 'pass', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$pass = $_POST['password'] ?? '';
if ($email && strlen($pass) >= 8) {
$hash = password_hash($pass, PASSWORD_DEFAULT);
$stmt = $pdo->prepare('INSERT INTO users (email, password_hash) VALUES (:e, :h)');
$stmt->execute([':e' => $email, ':h' => $hash]);
echo 'Cadastrado!';
}
<?php
function csrf_token() {
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf'];
}
function csrf_check($token) {
return hash_equals($_SESSION['csrf'] ?? '', $token);
}
Inclua o token com <input type="hidden" name="csrf" value="<?= csrf_token() ?>"> e valide no POST.
<?php
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$pass = $_POST['password'] ?? '';
if (!csrf_check($_POST['csrf'] ?? '')) { die('CSRF inválido'); }
$stmt = $pdo->prepare('SELECT id, password_hash FROM users WHERE email = :e LIMIT 1');
$stmt->execute([':e' => $email]);
$u = $stmt->fetch();
if ($u && password_verify($pass, $u['password_hash'])) {
$_SESSION['uid'] = $u['id'];
session_regenerate_id(true);
header('Location: /area-restrita.php'); exit;
}
echo 'Credenciais inválidas';
<?php
session_start();
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$p = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $p['path'], $p['domain'], $p['secure'], $p['httponly']);
}
session_destroy();
Remova os dados da sessão, destrua o cookie e finalize a sessão no servidor.
password_hash usa salt e custo (ex.: bcrypt/argon2), muito mais seguro do que hashes simples.Precisa gerar senhas, validar CPF/CNPJ ou criar QR Code? Acesse nossos Geradores e Validadores Online.