로그인 처리

This commit is contained in:
choibk 2025-12-04 21:01:53 +09:00
parent d4d655b870
commit d5b8ebf9f1
8 changed files with 147 additions and 14 deletions

View File

@ -1,17 +1,20 @@
<?php <?php
// Member Class file // Member Class file
class Member { class Member
{
// 멤버 변수, 프로퍼티 // 멤버 변수, 프로퍼티
private $conn; private $conn;
// 생성자 // 생성자
public function __construct($db) { public function __construct($db)
{
$this->conn = $db; // PDO 객체 주입 $this->conn = $db; // PDO 객체 주입
} }
// 아이디 중복체크용 멤버 함수, 메소드 // 아이디 중복체크용 멤버 함수, 메소드
public function id_exists($id) { public function id_exists($id)
{
$sql = "SELECT * FROM member WHERE id=:id"; $sql = "SELECT * FROM member WHERE id=:id";
$stmt = $this->conn->prepare($sql); $stmt = $this->conn->prepare($sql);
$stmt->bindParam(':id', $id); $stmt->bindParam(':id', $id);
@ -21,11 +24,13 @@ class Member {
} }
// 이메일 형식 체크 // 이메일 형식 체크
public function email_format_check($email) { public function email_format_check($email)
{
return filter_var($email, FILTER_VALIDATE_EMAIL); return filter_var($email, FILTER_VALIDATE_EMAIL);
} }
public function email_exists($email) { public function email_exists($email)
{
$sql = "SELECT * FROM member WHERE email=:email"; $sql = "SELECT * FROM member WHERE email=:email";
$stmt = $this->conn->prepare($sql); $stmt = $this->conn->prepare($sql);
$stmt->bindParam(':email', $email); $stmt->bindParam(':email', $email);
@ -35,7 +40,8 @@ class Member {
} }
// 회원 정보 입력 // 회원 정보 입력
public function input($marr) { public function input($marr)
{
$sql = "INSERT INTO member(id, password, name, email, zipcode, addr1, addr2, photo, create_at, ip) VALUES (:id, :password, :name, :email, :zipcode, :addr1, :addr2, :photo, NOW(), :ip)"; $sql = "INSERT INTO member(id, password, name, email, zipcode, addr1, addr2, photo, create_at, ip) VALUES (:id, :password, :name, :email, :zipcode, :addr1, :addr2, :photo, NOW(), :ip)";
$stmt = $this->conn->prepare($sql); $stmt = $this->conn->prepare($sql);
$stmt->bindParam(':id', $marr['id']); $stmt->bindParam(':id', $marr['id']);
@ -49,6 +55,28 @@ class Member {
$stmt->bindParam(':ip', $_SERVER['REMOTE_ADDR']); $stmt->bindParam(':ip', $_SERVER['REMOTE_ADDR']);
$stmt->execute(); $stmt->execute();
}
// 로그인
public function login($id, $pw)
{
// 아이디로 회원 정보 조회
$sql = "SELECT * FROM member WHERE id = :id LIMIT 1";
$stmt = $this->conn->prepare($sql);
$stmt->bindParam(':id', $id);
$stmt->execute();
$member = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$member) {
return false; // 아이디 없음
}
// 입력 비밀번호 vs DB 해시 비교
if (password_verify($pw, $member['password'])) {
return true;
} else {
return false;
}
} }
} }

View File

@ -4,7 +4,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $g_title ?></title> <title><?= (isset($g_title) && $g_title != '') ? $g_title : 'SOKUREE'; ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous"> integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
@ -31,19 +31,19 @@
</a> </a>
<ul class="nav nav-pills"> <ul class="nav nav-pills">
<li class="nav-item"> <li class="nav-item">
<a href="#" class="nav-link active" aria-current="page">Home</a> <a href="index.php" class="nav-link <?= ($menu_code == '') ? 'active': ''; ?>">Home</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="#" class="nav-link">Features</a> <a href="company.php" class="nav-link <?= ($menu_code == 'company') ? 'active': ''; ?>">회사소개</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="#" class="nav-link">Pricing</a> <a href="stipulation.php" class="nav-link <?= ($menu_code == 'member') ? 'active': ''; ?>">회원가입</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="#" class="nav-link">FAQs</a> <a href="board.php" class="nav-link <?= ($menu_code == 'board') ? 'active': ''; ?>">게시판</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="#" class="nav-link">About</a> <a href="login.php" class="nav-link <?= ($menu_code == 'login') ? 'active': ''; ?>">로그인</a>
</li> </li>
</ul> </ul>
</header> </header>

43
js/login.js Normal file
View File

@ -0,0 +1,43 @@
document.addEventListener("DOMContentLoaded", () => {
const btn_login = document.querySelector("#btn_login")
btn_login.addEventListener("click", () => {
const f_id = document.querySelector("#f_id")
if(f_id.value == '') {
alert('아이디를 입력하세요')
f_id.focus()
return false
}
const f_pw = document.querySelector("#f_pw")
if(f_pw.value == '') {
alert('비밀번호를 입력하세요')
f_pw.focus()
return false
}
// AJAX
const xhr = new XMLHttpRequest()
xhr.open("POST", "./pg/login_process.php", true)
const f1 = new FormData()
f1.append("id", f_id.value)
f1.append("pw", f_pw.value)
xhr.send(f1)
xhr.onload = () => {
if (xhr.status == 200) {
const data = JSON.parse(xhr.responseText);
console.log(data);
if (data.result === 'login_success') {
alert('로그인 성공!');
location.href = "/member/index.php"; // 이동
} else if (data.result === 'login_fail') {
alert('아이디 또는 비밀번호가 일치하지 않습니다.');
}
} else {
alert('로그인에 실패하였습니다. 다시 시도해 주세요');
}
}
})
})

29
login.php Normal file
View File

@ -0,0 +1,29 @@
<?php
$g_title = 'LogIn';
$js_array = ['js/login.js'];
$menu_code = 'login';
include 'header.php';
?>
<main class="mx-auto border rounded-2 p-5 d-flex gap-5" style="height: calc(100vh - 257px)">
<form method="post" class="w-25 mt-5 m-auto" action="">
<img src="./images/bootstrap-logo.png" width="72" alt="">
<h1 class="h3 mb-3"> 로그인 </h1>
<div class="form-floating mt-2">
<input type="text" class="form-control" id="f_id" placeholder="아이디 입력" autocomplete="off">
<label for="f_id">아이디</label>
</div>
<div class="form-floating mt-2">
<input type="password" class="form-control" id="f_pw" placeholder="비밀번호 입력" autocomplete="off">
<label for="f_pw">비밀번호</label>
</div>
<button class="w-100 mt-2 btn btn-lg btn-primary" id="btn_login" type="button">로그인</button>
</form>
</main>
<?php
include 'footer.php'
?>

View File

@ -9,6 +9,7 @@ if (!isset($_POST['chk']) || $_POST['chk'] != '1') {
$js_array = ['js/member_input.js']; $js_array = ['js/member_input.js'];
$g_title = '회원가입'; $g_title = '회원가입';
$menu_code = 'member';
include 'header.php'; include 'header.php';

31
pg/login_process.php Normal file
View File

@ -0,0 +1,31 @@
<?php
session_start();
$id = isset($_POST['id']) ? $_POST['id'] : '';
$pw = isset($_POST['pw']) ? $_POST['pw'] : '';
if ($id == '') {
die(json_encode(['result' => 'empty_id']));
}
if ($pw == '') {
die(json_encode(['result' => 'empty_pw']));
}
include '../config/dbconfig.php';
include '../config/member.php';
$mem = new Member($db);
if ($mem->login($id, $pw)) {
$_SESSION['ses_id'] = $id;
$arr = ['result' => 'login_success'];
} else {
$arr = ['result' => 'login_fail'];
}
// ★★★ 반드시 필요 ★★★
header("Content-Type: application/json; charset=utf-8");
echo json_encode($arr);
exit;

View File

@ -159,7 +159,7 @@ if ($mode === 'id_chk') {
// 9) 회원가입 완료 후 알림 + 홈(index.php) 이동 // 9) 회원가입 완료 후 알림 + 홈(index.php) 이동
echo "<script> echo "<script>
alert('회원가입이 완료되었습니다.'); alert('회원가입이 완료되었습니다.');
window.location.href = '/member/index.php'; window.location.href = '/member/login.php';
</script>"; </script>";
exit; exit;
} }

View File

@ -2,6 +2,7 @@
$js_array = [ 'js/member.js']; $js_array = [ 'js/member.js'];
$g_title = '약관'; $g_title = '약관';
$menu_code = 'member';
include 'header.php'; include 'header.php';