와우~ 대부분의 코드들이 이미 앞서 공지사항(notice.php)에서 본 내용돠 거의 비슷해.
다른 점은 본문 자리에 user_signup.php 가 들어 가는 거네.
먼저 이 user_signup.php의 큰 흐름 부터 살펴 보면 다음과 같아.
- user_signup.php
<?php
if (isset($_POST['submit'])) { //- [회원가입신청] 버튼을 클릭해 들어 왔으면
... 입력한 회원정보를 검증하고, yg_bbs 테이블에 저장하는 코드들...
}
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
... 입력폼 내용...
<button type="submit" name="submit">회원가입 신청</button>
</form>
① 회원가입을 위해 처음 signup.php 에 들어 오면 [회원가입 신청]을 아직 누르지 않은 상태야.
그러면 첫째 줄 if (isset($_POST['submit'])) 은 건너 뛰겠지?
그리고 바로 아래 쪽 의 <form>~</form> 으로 가서 신청양식을 화면에 보여줘.
② 신청양식에 내용을 입력하고 [회원가입 신청] 버튼을 누르면 <form...>의 action 이 $_SERVER['PHP_SELF'] (즉, 나 자신)이기 때문에 다시 signup.php 를 호출해.
그런데 이때는 submit 을 POST로 보내면서 호출하게 되겠지?
③ 다시 signup.php 에 들어오면 이제는 $_POST['submit'] 값이 있기 때문에 if (isset($_POST['submit'])) 아래 줄의 명령들 대로 움직이게 돼.
그 안에서 회원정보가 무사히 저장이 되고 나면 exit() 명령을 만나서 signup 을 끝내.
그러나 검증 과정에서 문제가 생기면 계속 아래 쪽으로 내려와서 다시 <form>~</form> 화면을 출력하게 돼.
(예를들어 입력한 아이디가 이미 사용중이라던지, 두 번 입력한 비밀번호가 서로 틀린다던지..)
다시 나온 화면에서 정보를 수정하고 다시 [회원가입 신청]을 누르면 이 ③ 번이 반복 될거야.
큰 흐름은 이해 되지?
이제 [회원가입 신청]을 클릭했을 때 만나는 코드 흐름을 볼까?
if (isset($_POST['submit'])) { //- [회원가입신청] 버튼을 클릭해 들어 왔으면
// POST로 넘어온 인자내용 보안검사
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME) or die('DB 접속에러'); // DB 접속
$uid = mysqli_real_escape_string($dbc, trim($_POST['uid']));
$uname = mysqli_real_escape_string($dbc, trim($_POST['uname']));
. . . 생략 . . .
$captcha = mysqli_real_escape_string($dbc, trim($_POST['captcha']));
if (!empty($uid) &&!empty($uname) && !empty($pass1) && !empty($pass2) && ($pass1 == $pass2) && !empty($captcha)) {
// 입력한 캡차가 맞는지 검사
if ($captcha <> $_SESSION['captcha']) {
echo '<p class="w3-text-red">입력한 자동가입방지 글자가 틀립니다. 다시 입력하세요.</p>';
} else {
// 이미 등록된 아이디 인지 검사위해 아이디 검색
$query = "SELECT * FROM yg_user WHERE uid = '$uid'";
$data = mysqli_query($dbc, $query);
if (mysqli_num_rows($data) == 0) {
// 쿼리결과 = 0 이면 중복 아이디가 아니므로 DB에 추가
$hash = password_hash($pass1, PASSWORD_DEFAULT); // 비번 암호화
$query = "INSERT INTO yg_user (uid, uname, pass, date, email, mobile, level)
VALUES ('$uid','$uname', '$hash', NOW(), '$email','$mobile',2)";
mysqli_query($dbc, $query) or die('DB 신규회원추가 에러');
// 축하 메시지 주고 나간다.
echo '<p class="w3-text-green">회원가입을 축하합니다. 가입한 아이디로 <a href="login.php">[로그인]</a> 하세요.</p>';
mysqli_close($dbc);
exit();
} else {
// 이미 등록된 동일 아이디가 있으면..
echo '<p class="w3-text-red">이미 사용중인 아이디 입니다. 다른 아이디를 사용하세요.</p>';
$uid = "";
}
}
}
else {
echo '<p class="w3-text-red">아이디,비번, 자동입력방지코드 중에서 빠진 것이 있습니다. 체크해 보세요.</p>';
}
}
먼저 신청양식에서 입력한 모든 정보를 mysqli_real_escape_string() 를 이용해서 보안검사를 하고,
입력한 항목 중에 아이디($uid) 이름($uname) 을 입력했는지, 두번의 비번($pass1, $pass2)을 모드 입력하고 그 번호가 같은지, 또 캡차($captcha) 항목도 입력했는지 확인하는 조건문이야.
여기서 틀리면 아래쪽 } 로 내려가서 에러메시지를 주고 <form> 화면을 출력할거야.
캡차(Captcha)란?
캡차는 Completely Automated Public Turing test to tell Computers and Humans Apart 의 앞글자를 뜻 약자로 웹페이지에 로봇 프로그램이 자동으로 회원가입한 뒤 악의적으로 스팸을 보내는 것을 차단하는 기능으로 로봇 프로그램이 인식할 수 없는 그림 속의 글자를 회원이 직접 입력하도록 하는 기능을 뜻해.
웹페이지의 회원가입시에는 거의 필수기능이지.
그렇지만 이 캡차도 AI 기술의 발달로 뚫리는 일이 많아져서 인기있는 사이트에서는 이메일인증 같은 이중, 삼중 방어를 하기도 해.
요기보드에 적용한 캡차는 학습을 위한 최소한의 기본기능을 제공하고 있지만 소형 사이트에서는 이 정도만 해도 충분하고 만일 문제가 생기면 그때 이메일, 휴대폰 인증 같은 추가 기능을 적용해도 충분할거라 믿어.
▶ if ($captcha <> $_SESSION['captcha'])
사용자가 입력한 캡차의 글자($captcha)와 세션에 저장된 캡차($_SESSION['captcha'])가 같은지 비교하는 문장이야. (세션에 대해서는 다음장 로그인에서 다시 자세히 설명할께.)
이때 세션($_SESSION )변수는 왜 사용했을까?
회원정보 입력을 하고 [회원가입 신청]을 하면 $_SERVER['PHP_SELF']에 의해 다시 이 signup.php 를 불러 오잖아.
그런데 다시 올 때는 이전 화면의 캡차정보를 알 수 없어.
그래서 이전 화면에서 캡차를 생성할 때 그 캡차문자를 세션($_SESSION['captcha']) 에 저장해 두었다 여기서 비교하는 거야.
캡차 그림을 생성하는 기능은 아래쪽의 아래 라인에서 captcha.php 를 실행하면서 만들어져.
<img src="<?php echo 'captcha.php'?>" />
즉 captcha.php 를 열어서 보면 캡차가 어떤 방식으로 생성되는지 알 수 있을거야.
다만 설명이 너무 길어져서 여기서는 생략할게. (대신 주석을 많이 달아 두었으니 참조하기 바래)
이 captcha.php 의 코드를 보면 임의의 영문자를 생성한 뒤에 이 값을 $_SESSION['captcha']에 저장하는 부분을 볼 수 있어.
▶ if (mysqli_num_rows($data) == 0)
캡차입력이 맞으면 다음 과정은 회원이 신청한 아이디가 이미 사용중인 아이디가 아닌지 체크하는 과정을 거쳐야 돼. 아이디가 중복이 되면 안되니까..
이 줄 위의 두 라인은 다음과 같아.
$query = "SELECT * FROM yg_user WHERE uid = '$uid'";
$data = mysqli_query($dbc, $query);
즉 회원이 신청한 아이디로 yg_table 에 검색을 해보는 거야.
만일 있으면 mysqli_num_rows($data) 값이 1 이나 그 이상이 되겠지? 0 이면 없는거야.
여기까지 체크를 마치고 나면 이제 DB 에 저장하면 되겠지?
▶ $hash = password_hash($pass1, PASSWORD_BCRYPT)
회원가입시 입력한 비밀번호를 암호화하는 함수야.
이 password_hash() 는 PHP 5.5 이상에서만 사용할 수 있어.
그러니 오래된 서버에서는 제대로 작동안할거야.
다른 웹보드들은 보통 오래된 서버에서도 작동하도록 이 함수를 잘 사용하지 않지만 '요기보드'는 새로 나온 제품인 만큼 암호화 함수로 이것을 사용하기로 했어.
불가피하게 PHP 5.5 이전 버전의 서버를 사용해야 한다면 md5() 또는 sha1() 같은 암호화 함수도 있으니 이것으로 교체해 사용하면 될거야.
(암호화에 대해서는 요기회원+ 메뉴에서 조금 더 상세하게 설명하도록 할께..)