데이터베이스 설정:
먼저, 사용자 비밀번호를 안전하게 저장하기 위해 해시된 비밀번호를 저장할 수 있도록 테이블을 생성합니다.
CREATE TABLE users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(30) NOT NULL,
password VARCHAR(255) NOT NULL
);
PHP 로그인 스크립트 (login.php):
<?php
session_start(); // 세션 시작
// HTTPS를 강제합니다(실제 배포 시 활성화)
// if ($_SERVER['HTTPS'] != "on") {
// header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
// exit();
// }
// 데이터베이스 설정
$servername = "localhost";
$dbUsername = "username"; // 데이터베이스 사용자 이름
$dbPassword = "password"; // 데이터베이스 비밀번호
$dbname = "myDatabase"; // 데이터베이스 이름
try {
// PDO 연결 객체 생성
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $dbUsername, $dbPassword);
// PDO 에러 모드를 예외로 설정
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 콘텐츠 보안 정책(CSP) 헤더 설정
// header("Content-Security-Policy: default-src 'self';");
// 로그인 데이터 받기
$user = $_POST['username'];
$pass = $_POST['password'];
// 입력 검증
if (empty($user) || empty($pass)) {
throw new Exception('Username and password are required.');
}
// 브루트 포스 공격 방지
if (!isset($_SESSION['login_attempts'])) {
$_SESSION['login_attempts'] = 0;
}
if ($_SESSION['login_attempts'] > 5) {
throw new Exception('Too many login attempts. Please try again later.');
}
// 사용자 검증
$stmt = $conn->prepare("SELECT id, password FROM users WHERE username = :username");
$stmt->bindParam(':username', $user);
$stmt->execute();
if ($stmt->rowCount() > 0) {
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (password_verify($pass, $row['password'])) {
// 로그인 성공
$_SESSION['user_id'] = $row['id'];
$_SESSION['login_attempts'] = 0; // 시도 횟수 초기화
echo "Welcome " . htmlspecialchars($user) . "!";
} else {
// 비밀번호 불일치
$_SESSION['login_attempts'] += 1;
echo "Invalid password";
}
} else {
// 사용자가 존재하지 않음
$_SESSION['login_attempts'] += 1;
echo "Invalid username";
}
} catch(PDOException $e) {
echo "Error: " . $e->getMessage();
} catch(Exception $e) {
echo "Error: " . $e->getMessage();
}
$conn = null;
?>
- HTTPS 강제 리다이렉: 안전하지 않은 HTTP 대신에 HTTPS를 사용하여 데이터를 암호화합니다. 주석 처리된 부분을 실제 환경에서 활성화해야 합니다.
- 콘텐츠 보안 정책(CSP): XSS 공격을 방지하기 위해 CSP 헤더를 설정합니다. 주석 처리된 헤더 설정을 실제 환경에서 활성화해야 합니다.
- 브루트 포스 공격 방지: 로그인 시도 횟수를 세션에 저장하여 무차별 대입 공격을 방지합니다.
'PHP' 카테고리의 다른 글
간단하게 폼메일 만드는 방법 (1) | 2023.12.24 |
---|