| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 31 |
- 로그인
- MySQL
- php 회원가입
- 운영체제
- sql 인젝션 공격 방법
- HTML
- sql 인젝션 방어
- 명품 운영체제 8장
- 생능출판
- Mac
- 게시판
- 로그인 구현
- 5장 연습문제
- 명품 운영체제
- 회원가입 구현
- 연습문제 답안
- 배치 운영체제
- 연습문제 답
- colima
- php 로그인
- 연습문제
- DB
- php
- 복합문제
- 명품 운영체제 7장
- php 게시판 만들기
- 웹 서버
- 명품 운영체제 9장
- 명품 운영체제 5장 복합문제
- 게시판 만들기
- Today
- Total
눈사람의 해킹공부
[PHP] 회원가입, 로그인 페이지 만들기(DB활용) 본문

이 포스트에서는 php 세션을 이용한 간단한 로그인 페이지 만들기를 다룹니다.
지난 포스트 했던 DB를 활용하지 않고 했던 버전과 달리 이번에는 데이터베이스(mysql)을 활용하여 로그인 정보를 저장하고 로그인되는 페이지를 만들어보겠습니다.
먼저 로직은 이렇습니다.
- 메인(index.php)은 로그인 페이지 링크를 생성합니다.
- 로그인 페이지(login.php)는 로그인용 폼을 만들고 회원가입 페이지로가는 버튼과 로그인 처리용 페이지를 만들어서 처리합니다.
- 회원가입 페이지에서 회원가입을 할 경우 아이디와 비밀번호, 닉네임을 데이터베이스에 저장합니다.
- 로그인 처리 페이지(login_ok.php)는 데이터베이스에 저장한 계정 정보를 대조하여 로그인 성공 시 그 상태로 메인으로 복귀, 실패 시는 실패 안내 후 로그인 페이지로 돌아옵니다.
- 메인 페이지에 로그아웃 용 페이지로 가는 링크가 표시됩니다.
- 로그아웃 페이지(logout.php)는 세션을 삭제하여 로그아웃 처리하고 위의 1번으로 돌아갑니다.
이렇게 구현한다고 할 때, 이를 위해 다음과 같이 6개의 php 파일을 만들어 봅시다.
지난 포스트와 다른 점은 login_ok.php에서 로그인정보를 대조할 때, 데이터베이스를 활용한다는 점, register.php에서 회원가입을 한다는 점이 추가되었습니다.
데이터베이스는 ID/PW가 각각 test, pass이며 , users 테이블에 userid, password, name 속성을 가집니다.
CSS 파일은 지난 포스트와 동일하게 참고합니다.
index.php
<!DOCTYPE html>
<?php session_start(); ?>
<html>
<head>
<meta charset="utf-8" />
<title>PHP Session Login Test</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Snowman</h1>
<?php
if(!isset($_SESSION['user_id']) || !isset($_SESSION['user_name'])) {
echo "<p>로그인을 해 주세요. <a href=\"login.php\">[로그인]</a></p>";
} else {
$user_id = $_SESSION['user_id'];
$user_name = $_SESSION['user_name'];
echo "<p><strong>$user_name</strong>($user_id)님 환영합니다.";
echo "<a href=\"logout.php\">[로그아웃]</a></p>";
}
?>
<hr />
<p> My First php file.</p>
</body>
</html>
login.php
<!DOCTYPE html>
<?php session_start(); ?>
<html>
<head>
<meta charset="utf-8" />
<title>PHP Session Login Test</title>
<link rel="stylesheet" href="style_login.css">
</head>
<body>
<div class="container">
<h1>Snowman</h1>
<?php
if(!isset($_SESSION['user_id']) || !isset($_SESSION['user_name'])) { ?>
<form method="post" action="login_ok.php">
<p>아이디: <input type="text" name="user_id"/> </p>
<p>비밀번호: <input type="password" name="user_pw"/> </p>
<a href="register.php">[회원가입]</a></p>
<p><input type="submit" value="로그인"/> </p>
</form>
<?php } else {
$user_id = $_SESSION['user_id'];
$user_name = $_SESSION['user_name'];
echo "<p><strong>$user_name</strong>($user_id)님은 이미 로그인하고 있습니다. ";
echo "<a href=\"index.php\">[돌아가기]</a> ";
echo "<a href=\"logout.php\">[로그아웃]</a></p>";
} ?>
</body>
</html>
login_ok.php
<?php
// 에러 검증용 코드입니다.
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
session_start(); // 세션을 시작합니다.
$dbHost = '127.0.0.1'; // 데이터베이스 호스트
$dbUser = 'test'; // 데이터베이스 사용자 이름
$dbPass = 'pass'; // 데이터베이스 비밀번호
$dbName = 'TEST'; // 데이터베이스 이름
// 데이터베이스 연결
$conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName);
// 연결 오류 확인
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// POST 데이터 검증 및 정제
if (!isset($_POST['user_id']) || !isset($_POST['user_pw'])) {
header("Content-Type: text/html; charset=UTF-8");
echo "<script>alert('아이디 또는 비밀번호가 빠졌거나 잘못된 접근입니다.');";
echo "window.location.replace('login.php');</script>";
exit;
}
$user_id = $conn->real_escape_string($_POST['user_id']);
$user_pw = $_POST['user_pw'];
// 데이터베이스 쿼리
$sql = "SELECT * FROM users WHERE userid = '$user_id'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
if (password_verify($user_pw, $row['password'])) {
// 인증 성공, 세션 변수 설정
$_SESSION['user_id'] = $user_id;
$_SESSION['user_name'] = $row['name'];
// 페이지 리다이렉션
header("Location: index.php");
exit;
} else {
// 인증 실패
header("Content-Type: text/html; charset=UTF-8");
echo "<script>alert('아이디 또는 비밀번호가 잘못되었습니다.');";
echo "window.location.replace('login.php');</script>";
exit;
}
} else {
// 사용자가 존재하지 않음
header("Content-Type: text/html; charset=UTF-8");
echo "<script>alert('아이디 또는 비밀번호가 잘못되었습니다.');";
echo "window.location.replace('login.php');</script>";
exit;
}
$conn->close(); // 데이터베이스 연결 종료
?>
로그인 처리용 페이지입니다. 여기서는 데이터베이스에서 사용자 정보가 저장된 테이블을 가져와 로그인 페이지에서 받아온 아이디와 비밀번호를 비교하여 다르면 로그인 실패로 처리하여 다시 로그인 페이지로 이동시키고 동일하면 로그인합니다.
logout.php
<?php
session_start();
session_destroy();
?>
<meta http-equiv="refresh" content="0;url=index.php" />
지난 포스트와 동일한 로그아웃 페이지입니다.
저장된 세션을 불러온 후 그 세션 정보를 완전히 삭제함으로써 로그인 상태에서 벗어난 후, 다시 메인 페이지로 돌아갑니다.
register.php
<?php
$username = $password = $password_confirm = $nickname = "";
$wu = $wp = 0; // 변수 초기화
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
$password_confirm = $_POST['password_confirm'];
$nickname = $_POST['nickname']; // 닉네임을 POST 데이터에서 가져옵니다.
if ($username != "") {
$jb_conn = mysqli_connect('localhost', 'test', 'pass', 'TEST');
if (!$jb_conn) {
die("Connection failed: " . mysqli_connect_error());
}
// SQL 인젝션 방지
$username = mysqli_real_escape_string($jb_conn, $username); // SQL 인젝션 방지 처리
$nickname = mysqli_real_escape_string($jb_conn, $nickname); // 닉네임에 대해서도 SQL 인젝션 방지 처리
$jb_sql = "SELECT userid FROM users WHERE userid = '$username';";
$jb_result = mysqli_query($jb_conn, $jb_sql);
if ($jb_result && mysqli_fetch_array($jb_result)) {
$wu = 1; // 사용자 이름이 이미 존재합니다.
} elseif ($password !== $password_confirm) {
$wp = 1; // 비밀번호가 일치하지 않습니다.
} else {
$encrypted_password = password_hash($password, PASSWORD_DEFAULT);
$jb_sql_add_user = "INSERT INTO users (userid, password, name) VALUES ('$username', '$encrypted_password', '$nickname');";
if (!mysqli_query($jb_conn, $jb_sql_add_user)) {
die("Error: " . $jb_sql_add_user . "<br>" . mysqli_error($jb_conn));
}
header('Location: register_ok.php');
exit;
}
mysqli_close($jb_conn);
}
}
?>
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title>회원 가입</title>
</head>
<body>
<h1>회원 가입</h1>
<form action="register.php" method="POST">
<p><input type="text" name="username" placeholder="사용자 ID" required></p>
<p><input type="password" name="password" placeholder="비밀번호" required></p>
<p><input type="password" name="password_confirm" placeholder="비밀번호 확인" required></p>
<p><input type="text" name="nickname" placeholder="닉네임" required></p>
<p><input type="submit" value="회원 가입"></p>
<?php
if ($wu === 1) {
echo "<p>사용자 ID가 중복되었습니다.</p>";
}
if ($wp === 1) {
echo "<p>비밀번호가 일치하지 않습니다.</p>";
}
?>
</form>
</body>
</html>
위 코드를 설명하겠습니다.
PHP 부분:
- 변수 초기화:
- 사용자 이름($username), 비밀번호($password), 비밀번호 확인($password_confirm), 닉네임($nickname)을 빈 문자열로 초기화합니다.
- $wu와 $wp는 각각 "사용자 이름 중복"과 "비밀번호 불일치" 상황을 나타내는 플래그로, 초기값은 0(오류 없음)입니다.
- POST 요청 처리:
- 폼에서 전송된 데이터가 POST 방식으로 전송되었는지 확인합니다.
- POST 데이터에서 username, password, password_confirm, nickname 값을 가져옵니다.
- 데이터베이스 연결:
- mysqli_connect() 함수를 사용하여 MySQL 데이터베이스에 연결을 시도합니다. 연결 실패 시 오류 메시지를 출력하고 스크립트를 종료합니다.
- SQL 인젝션 방지:
- 입력받은 username과 nickname에 대해 mysqli_real_escape_string() 함수를 사용하여 SQL 인젝션 공격을 방지합니다.
- 사용자 이름 중복 확인:
- SELECT 쿼리를 실행하여 입력받은 사용자 이름이 데이터베이스에 이미 존재하는지 확인합니다.
- 사용자 이름이 데이터베이스에 존재하면 $wu 플래그를 1로 설정합니다.
- 비밀번호 일치 확인:
- 입력받은 비밀번호와 비밀번호 확인이 일치하지 않으면 $wp 플래그를 1로 설정합니다.
- 사용자 등록:
- 사용자 이름 중복이 없고 비밀번호가 일치하면, 비밀번호를 password_hash() 함수를 사용하여 해시합니다.
- INSERT 쿼리를 실행하여 사용자 이름, 해시된 비밀번호, 닉네임을 데이터베이스에 저장합니다.
- 쿼리 실행 후 register_ok.php 페이지로 리디렉트합니다.
- 데이터베이스 연결 종료:
- 모든 데이터베이스 작업이 끝나면 mysqli_close() 함수를 사용하여 연결을 닫습니다.
HTML 부분:
- 회원가입 폼:
- 사용자에게 입력을 받을 수 있는 HTML 폼을 제공합니다.
- 폼에는 사용자 ID, 비밀번호, 비밀번호 확인, 닉네임을 입력할 수 있는 필드가 있습니다.
- 모든 입력 필드는 required 속성을 가지고 있어서 비어 있을 수 없습니다.
- 폼 제출 버튼:
- 사용자가 폼을 제출할 수 있는 제출 버튼이 있습니다.
- 오류 메시지 표시:
- PHP에서 설정한 $wu와 $wp 플래그의 값에 따라 오류 메시지를 표시합니다.
- 사용자 ID가 중복되었을 경우 "사용자 ID가 중복되었습니다."라는 메시지를 출력합니다.
- 비밀번호가 일치하지 않을 경우 "비밀번호가 일치하지 않습니다."라는 메시지를 출력합니다.
register_ok.php
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title>회원 가입</title>
</head>
<body>
<h1>회원 가입이 완료되었습니다.</h1>
<?php
echo "<a href=\"login.php\">[로그인하기]</a></p>"; ?>
</body>
</html>
register.php에서 정상적으로 회원가입되어 넘어오면 회원가입이 완료되었다는 메시지와 함께 로그인창으로 넘어갈 수 있는 버튼이 보여집니다.
이렇게 해서 간단한 회원가입 기능과 로그인페이지의 구현이 완료됩니다.
'웹' 카테고리의 다른 글
| [PHP/MYSQL] 회원 전용 게시판 만들기 3. 게시글 보기, 작성, 수정, 삭제 (0) | 2023.11.21 |
|---|---|
| [PHP/MYSQL] 회원 전용 게시판 만들기 2. 회원가입 및 로그인 (2) | 2023.11.20 |
| [PHP/MYSQL] 회원 전용 게시판 만들기 1. 메인페이지 및 헤더(푸터)파일 (0) | 2023.11.20 |
| [PHP] 로그인 페이지 구현과 CSS를 이용한 디자인 (0) | 2023.10.30 |
| 웹 서버(Web Server)와 WAS(Web Application Server) (0) | 2023.10.26 |