2주차 과제
- 회원가입 페이지 만들기 (기능 구현)
- 로그인 페이지 ( DB 연동하기)
메인 폴더 안에 member 폴더를 생성해서 코드를 작성했다. (CSS 파일은 메인 폴더 안에 CSS 폴더 생성해서 저장)
회원 정보를 저장할 memeber 테이블
로그인 페이지
login.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="../css/style.css" />
<title>로그인</title>
<script type="text/javascript">
function login_check() {
var userid = document.getElementById("id");
var userpw = document.getElementById("pw");
if (userid.value == "") {
var id_txt = document.querySelector(".err_id");
id_txt.textContent = "아이디를 입력하세요.";
userid.focus();
return false;
};
if (userpw.value == "") {
var pw_txt = document.querySelector(".err_pw");
pw_txt.textContent = "비밀번호를 입력하세요.";
userpw.focus();
return false;
};
};
</script>
</head>
<body>
<?php
session_start();
if (isset($_SESSION['name'])) {
echo "<script>
alert(\"이미 로그인 하셨습니다.\");
location.href = \"../main/index.php\";
</script>";
} else { ?>
<div id="login_wrap" class="wrap">
<div>
<h1>Login</h1>
<form action="login_proc.php" method="post" name="loginform" id="login_form" class="form">
<p><input type="text" name="id" id="id" placeholder="ID"></p>
<span class="err_id"></span> // 경고문 출력
<p><input type="password" name="pw" id="pw" placeholder="Password"></p>
<span class="err_pw"></span> // 경고문 출력
<p><input type="submit" value="로그인" class="form_btn"></p>
<p class="pre_btn"><a href="regist.php">회원가입</a></p>
</form>
</div>
</div>
</body>
</html>
<?php
}
?>
자바스크립트로 아이디나 비밀번호 입력폼이 공백일 때 입력하라는 경고문을 출력하고, 커서가 가도록 하였다.
style.css
회원가입 화면이랑 같이 쓰는 파일이라 정리가 좀 안돼있어 보기 어렵다 (...나도 헷갈림)
/* style.css */
* {
padding: 0;
margin: 0;
}
a {
text-decoration: none;
color: #000;
}
/* body를 가운데 정렬하기 위해 html에 flex를 주었습니다. */
html {
width: 100%;
height: 100%;
display: flex;
align-items: center;
}
body {
width: 100%;
margin: 0 auto;
text-align: center; /* 회원가입 글자 */
background: linear-gradient(black, gray);
font-family: sans-serif;
}
.wrap {
/* 하얀 상자 */
width: 500px; /* body 밑 div 상자 */
height: 650px;
margin: 0 auto;
background-color: #fff;
border-radius: 20px; /* 상자 둥근 정도 */
display: flex;
justify-content: center;
align-items: center;
}
.wrap > div {
width: 100%;
margin: 0 100px;
}
h1 {
margin-bottom: 20px;
}
/* submit을 제외한 나머지 input 태그에 적용 */
.wrap .form input:not(input[type="submit"], input[type="checkbox"]) {
border: 1px solid #d9d9d9;
width: 400px;
height: 40px;
margin: 5px;
padding-left: 10px;
border-radius: 10px;
box-sizing: border-box;
font-size: 16px;
}
/* 체크 버튼 스타일 지정 */
#regist_wrap #regist_form input#checkIdBtn {
position: relative;
top: -2px;
width: 45px;
height: 35px;
margin-left: 0;
padding-left: 0;
border: 0;
box-sizing: content-box;
background: gray;
font-size: 12px;
font-weight: bold;
color: #fff;
cursor: pointer;
}
#regist_wrap #regist_form input#check_button {
position: relative;
top: -2px;
width: 100px;
height: 28px;
font-size: 12px;
margin-left: 0;
padding-left: 0;
/* border: 0; */
box-sizing: content-box;
background: white;
border-color: black;
/* font-weight: bold; */
/* color: white; */
cursor: pointer;
}
/* 체크 시 표시될 영역 비표시(자바스크립트로 제어) */
#regist_wrap #regist_form #result {
display: none;
}
#login_wrap .forgetpw {
text-align: left;
font-size: 14px;
margin: 0 0 10px 10px;
cursor: pointer;
}
.wrap .form_btn {
/* wrap 안에 있는 form_btn 클래스 */
width: 400px;
height: 50px;
margin: 10px;
border-radius: 5px;
border: 0;
background: black;
color: #fff;
font-weight: bold;
font-size: 18px;
cursor: pointer;
}
#login_wrap .forgetpw a,
#regist_wrap .pre_btn a {
/* a 태그에 적용 */
color: red;
}
#login_wrap .pre_btn a {
font-size: 13px;
color: gray;
}
로그인 페이지 화면
login_proc.php
<?php
session_start();
include "../db_conn.php";
$id = $_POST['id'];
$pw = $_POST['pw'];
$hashed_pw = hash('sha256', $pw);
//아이디 존재 여부 검사
$sql = "select * from member where userid='$id'";
$result = mysqli_query($db_conn, $sql);
$row = mysqli_fetch_array($result);
if (!$row) { // 아이디가 존재하지 않으면 로그인 페이지로
echo "<script>
alert(\"일치하는 아이디가 없습니다.\");
history.back();
</script>";
exit;
} else { // 아이디가 존재하면 비밀번호 확인
if ($row['userpw'] != $hashed_pw) { // 비밀번호 불일치 시 로그인 페이지로
echo "<script>
alert(\"비밀번호가 일치하지 않습니다.\");
history.back();
</script>";
exit;
} else { // 비밀번호 일치 시 세션 변수 생성
$_SESSION['name'] = $row['username'];
$_SESSION['id'] = $row['userid'];
mysqli_close($db_conn);
header("Location: ../main/index.php");
}
}
비밀번호는 보안을 위해 해시값으로 DB에 저장할 것이므로 hash함수를 이용해서 비밀번호를 변환하여 확인한다. (아래 회원가입 코드에서 확인)
먼저 DB에 아이디가 존재하는지 확인한 다음 비밀번호가 일치하는 지 확인한다.
(식별 / 인증 분리)
비밀번호까지 확인되어 로그인이 되었다면 세션 변수를 생성해서 사용자의 이름과 id를 저장한다.
회원가입 페이지
[regist.php]
<?php
include "db_conn.php";
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="../css/style.css" />
<script type="text/javascript" src="./regist.js"></script>
<title>회원가입</title>
</head>
<body>
<?php
session_start();
if (isset($_SESSION['name'])) {
echo "<script>
alert(\"이미 로그인 하셨습니다.\");
location.href = \"../main/index.php\";
</script>";
} else { ?>
<div id="regist_wrap" class="wrap">
<div>
<h1>Join</h1>
<form action="regist_proc.php" method="post" name="regiform" id="regist_form" class="form" onsubmit="return sendit()">
<p><input type="text" name="name" id="username" placeholder="Name (한글, 영어)"></p>
<p><input type="text" name="id" id="userid" placeholder="ID">
<input type="hidden" name="decide_id" id="decide_id">
</p>
<p><span id="decide" style='color:red; font-size:13px;'>* ID 중복 여부를 확인해주세요. </span>
<input type="button" id="check_button" value="ID 중복체크" onclick="checkId();">
</p>
<p><input type="password" name="pw" id="userpw" placeholder="Password"></p>
<p><input type="password" name="pw_ch" id="userpw_ch" placeholder="Password Check"></p>
<p><input style="width:210px;" type="text" name="email" id="useremail" placeholder="Email">@
<select style="width:165px; height:40px; border: 1px solid #d9d9d9; border-radius: 10px;font-size: 14px;" name="emadress">
<option value="naver.com">naver.com</option>
<option value="gmail.com">gmail.com</option>
<option value="daum.net">daum.net</option>
</select>
</p>
<p><input type="text" name="phone" id="userphone" placeholder="Phone Number"></p>
<p><span style='color:red; font-size:13px; float:left;'> "-" 없이 11자리 숫자만 입력</span>
<input type="submit" value="회원가입" id="join_button" class="form_btn" disabled=true>
</p>
<p><a href="login.php" style="color: gray; font-size:13px;">로그인</a></p>
</form>
</div>
</div>
</body>
</html>
<?php
}
?>
[regist.js]
function decide() {
document.getElementById("decide").innerHTML =
"<span style='color:blue;'>사용 가능한 아이디입니다. </span>";
document.getElementById("decide_id").value =
document.getElementById("userid").value;
document.getElementById("userid").disabled = true;
document.getElementById("join_button").disabled = false;
document.getElementById("check_button").value = "다른 ID로 변경";
document.getElementById("check_button").setAttribute("onclick", "change()");
}
function change() {
document.getElementById("decide").innerHTML =
"<span style='color:red;'>ID 중복 여부를 확인해주세요. </span>";
document.getElementById("userid").disabled = false;
document.getElementById("userid").value = "";
document.getElementById("join_button").disabled = true;
document.getElementById("check_button").value = "ID 중복 검사";
document.getElementById("check_button").setAttribute("onclick", "checkId()");
}
function checkId() {
var userid = document.getElementById("userid").value;
if (userid) {
url = "check.php?userid=" + userid;
window.open(url, "chkid", "width=400,height=200");
} else {
alert("아이디를 입력하세요.");
}
}
const sendit = () => {
const userid = document.regiform.userid;
const userpw = document.regiform.userpw;
const userpw_ch = document.regiform.userpw_ch;
const username = document.regiform.username;
const userphone = document.regiform.userphone;
const useremail = document.regiform.useremail;
// username값이 비어있으면 실행.
if (username.value == "") {
alert("이름을 입력해주세요.");
username.focus();
return false;
}
// 한글 이름 형식 정규식
const expNameText = /[가-힣a-zA-Z0-9]+$/;
// username값이 정규식에 부합한지 체크
if (!expNameText.test(username.value)) {
alert("이름 형식이 맞지않습니다. 형식에 맞게 입력해주세요.");
username.focus();
return false;
}
if (username.value.length > 10) {
alert("이름은 10글자 이하로 입력해주세요.");
username.focus();
return false;
}
if (userid.value == "") {
alert("아이디를 입력해주세요.");
userid.focus();
return false;
}
// userid값이 4자 이상 12자 이하를 벗어나면 실행.
if (userid.value.length < 3 || userid.value.length > 10) {
alert("아이디는 3자 이상 10자 이하로 입력해주세요.");
userid.focus();
return false;
}
// userpw값이 비어있으면 실행.
if (userpw.value == "") {
alert("비밀번호를 입력해주세요.");
userpw.focus();
return false;
}
// userpw_ch값이 비어있으면 실행.
if (userpw_ch.value == "") {
alert("비밀번호 확인을 입력해주세요.");
userpw_ch.focus();
return false;
}
// userpw값이 6자 이상 20자 이하를 벗어나면 실행.
if (userpw.value.length < 3 || userpw.value.length > 20) {
alert("비밀번호는 3자 이상 20자 이하로 입력해주세요.");
userpw.focus();
return false;
}
// userpw값과 userpw_ch값이 다르면 실행.
if (userpw.value != userpw_ch.value) {
alert("비밀번호가 일치하지 않습니다. 다시 입력해주세요.");
userpw_ch.focus();
return false;
}
// useremail값이 비어있으면 알림창을 띄우고 input에 포커스를 맞춘 뒤 False를 리턴한다.
if (useremail.value == "") {
alert("이메일을 입력해주세요.");
useremail.focus();
return false;
}
// 이메일 형식 정규식
const expEmailText = /[a-zA-Z0-9]+$/;
// useremail값이 정규식에 부합한지 체크
if (!expEmailText.test(useremail.value)) {
alert("이메일 형식이 맞지 않습니다.");
useremail.focus();
return false;
}
// userphone값이 비어있으면 실행.
if (userphone.value == "") {
alert("핸드폰 번호를 입력해주세요.");
userphone.focus();
return false;
}
// 핸드폰 번호 형식 정규식
const expHpText = /^\d{3}\d{3,4}\d{4}$/;
// userphone값이 정규식에 부합한지 체크
if (!expHpText.test(userphone.value)) {
alert("핸드폰 번호 형식이 맞지않습니다.");
userphone.focus();
return false;
}
return true;
};
checkID 함수는 id 중복체크 시에 중복여부를 새로운 창을 띄어 보여준다.
decide 함수는 id 중복체크 후 사용을 확정했을 때 (이 때만 회원가입 버튼이 활성화됨),
change 함수는 id가 중복되었거나 변경을 원할 경우에 실행된다.
sendit 함수는 각 입력 값의 유효성을 검사한다.
[sytel.css]
로그인 페이지와 동일
회원가입 페이지 화면
중복확인
id에 123qwe를 입력하고 'ID 중복체크' 버튼을 클릭하면
새로운 창이 나오며 id의 사용 가능 여부를 알려준다.
'이 ID 사용' 버튼을 클릭하면
'ID 중복체크' => '다른 ID로 변경' (decide 함수 실행)
'다른 ID로 변경'을 클릭하면
다시 처음 상태로 초기화된다. (change 함수 실행)
[regist_proc.php]
<?php
include "../db_conn.php";
$pw = $_POST['pw'];
$hashed_pw = hash('sha256', $pw);
$email = $_POST['email'] . '@' . $_POST['emadress'];
$sql = "insert into member values(null, '{$_POST['name']}', '{$_POST['decide_id']}','$hashed_pw', '$email','{$_POST['phone']}', now())";
$result = mysqli_query($db_conn, $sql);
/* $result = $db_conn -> query($sql);*/
// 입력이 됐으면 결과가 1
if ($result === false) { /* === 이면 자료형까지 일치하는지 확인 */
echo "저장에 문제가 생겼습니다. 관리자에게 문의 바랍니다.";
echo mysqli_error($db_conn);
} else { ?>
<script>
alert("회원가입이 완료되었습니다.")
location.href = "../main/index.php"
</script>;
<?php
}
?>
db_conn.php는 데이터베이스 연결을 위해 따로 저장해둔 파일이다.
회원가입에 성공하면 index 페이지로 이동하게 하였고, 실패하면 문제가 생겼다는 문자를 출력한다. 그리고 이후 코드가 노출되지 않도록 exit로 해당 코드를 완전히 빠져나온다.
'웹 모의해킹 스터디 > 웹 개발 (PHP | MySQL)' 카테고리의 다른 글
[php/mysql] 게시판 글 작성 구현하기 (3) | 2023.11.21 |
---|---|
[php/mysql] 게시판 리스트 구현하기 (메인 페이지) (0) | 2023.11.21 |
[php / mysql] 세션(session)을 이용한 로그인 / 로그아웃 구현 (0) | 2023.11.17 |
[3주차] [php / mysql] 4가지 로그인 과정 구현 (0) | 2023.11.15 |
[1주차] [html / css] 로그인 페이지 만들기 (1) | 2023.11.01 |