모의해킹 스터디 과제

모의해킹 스터디 2주차 과제: 회원가입 페이지, 로그인 DB 연동

whydontyoushovel 2024. 11. 1. 01:51

 

※ 2주차 과제

≫ 회원가입 페이지 만들기

  • 2주차의 완성본
  • 로직
  • 겪은 문제들

≫ 로그인 페이지에 DB 연동시키기

  • 2주차의 완성본
  • 로직
  • 겪은 문제들

 

 

♨ 회원가입 페이지 만들기

파일은 총 4개가 만들어졌다

 

    1) registration.php : 가입 페이지, 오류문 출력

    2) regi_style.css : 가입 페이지 디자인

    3) regi_proc.php : DB연동, INSERT

    4) vali_check.php : 유효성 검사 결과 반환

 

 

  • 2주차 완성본

1) registration.php :

가입 페이지, 유효성 검사 통과 못한 데이터에 오류문 출력

<!DOCTYPE html>
<html>

<?php
    session_start();


    $id_error = "";
    $pw_error = "";

    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);


      /*  require_once('vali_check.php');*/
?>

    <head>         
        <link href="./regi_style.css" rel="stylesheet">
        <meta charset="UTF-8">
        <title>
            로그인 페이지
        </title>
    </head>


    <body>`
        <div class="logo">
            <img src="./img/logo.png"/>
        </div>
        <form method="POST" action="regi_proc.php">
            <div>
                <input type="text" name="regi_id" placeholder="아이디" class="regi-info"/>
            </div>
            <div>
                <input type="password" name="regi_pass" placeholder="비밀번호" class="regi-info"/>
            </div>
            <div>
                <input type="password" name="regi_pass_ok" placeholder="비밀번호 확인" class="regi-info"/>
            </div>
            <div>
                <input type="text" name="email" placeholder="이메일 주소" class="regi-info"/>
            </div>
            <div>
                <input type="text" name="user-name" placeholder="사용할 이름" class="regi-info"/>
            </div>
        
            /*<p style="color:red"><?php echo $id_error; ?></p>
            <p style="color:red"><?php echo $pw_error; ?></p>*/

                <?php

                    $id_error = isset($_SESSION['id_error'])? $_SESSION['id_error'] : "";
                    $pw_error = isset($_SESSION['pw_error'])? $_SESSION['pw_error'] : "";

                    echo $pw_error;
                    echo $id_error;


                    unset($_SESSION['id_error']);
                    unset($_SESSION['pw_error']);
                                    
                ?>
            <div>
                <input type="submit" name="submit" value="가입하기" class="button"/>
            </div>

        </form>

    </body>

</html>

 

 

2) regi_style.css :

가입 페이지의 디자인

* {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 16px;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    text-align: center;
}

body {
    display: flex;
    flex-direction: column; /* 로고가 위, 콘텐츠가 아래로 배치 */
    justify-content: center;
    align-items: center;
    height: 100vh;
    padding: 20px;
    overflow: scroll;
}

.logo {
    align-items: center;
    text-align: center;
    margin-bottom: 40px; /* 로고 아래 여백 */
}

.logo img {
    width: 65%; /* 로고 크기 */
}

form {
    display: flex;
    flex-direction: column;
    padding: 20px;
    margin-right: 100px;
    border-radius: 10px;
    width: 380px;
    height: 467px;
    border: solid 1px;
}

.regi-info {
    align-items: center;
    width: 300px;
    height: 40px;
    margin: 10px;
}

.button {
    width: 300px;
    height: 40px;
    margin: 80px 0;
    background-color: rgb(219, 217, 215);
}

.button:hover {
    background-color: rgb(240,130,0);
}

 

 

3) regi_proc.php :

유효성 검사를 통과한 데이터를 DB에 저장. 통과하지 못하면 registration.php로 리다이렉션

<?php

    session_start();

    define('DB_SERVER', 'localhost');
    define('DB_USER', '안알랴줌');
    define('DB_PASS', '안알랴줌22');
    define('DB_NAME', 'registration');

    $db_conn = mysqli_connect(DB_SERVER,DB_USER,DB_PASS,DB_NAME);

    if($db_conn) {
        echo "인증 오류";
    } //디버깅 코드

    $regi_id = $_POST['regi_id'];
    $regi_pass = $_POST['regi_pass'];
    $regi_pass_ok = $_POST['regi_pass_ok'];
    $email = $_POST['email'];
    $nick = $_POST['user-name'];
    $submit = $_POST['submit'];


    $sql_select = "SELECT * FROM registration_list WHERE id='$regi_id'";
    
    $select_result = mysqli_query($db_conn, $sql_select);

    $row = mysqli_fetch_array($select_result); //SELECT문


    require_once('vali_check.php'); //해당 파일의 함수를 수행할 수 있도록 연결해줌
 
    $login_func = login_check1($regi_id,$row['id']);
    $login_func2 = login_check2($regi_pass,$regi_pass_ok); //유효성 검사


    if ($login_func && $login_func2) {
            
        $sql_insert = "INSERT INTO registration_list(idx,id,pass,email,nickname) values(null, '$regi_id','$regi_pass','$email','$nick')";

        $insert_result= mysqli_query($db_conn, $sql_insert);

        if (!$insert_result) {
            die("mysqli_error($db_conn)");
        }//디버깅 코드
    
        header("location: index.html"); //INSERT문 + 리다이렉트
        exit;
        
    } else {
        if (!$login_func) {
            $_SESSION['id_error'] = "이미 사용 중인 아이디입니다.";
            header("location: registration.php");
            exit;
        }

        if (!$login_func2) {
            $_SESSION['pw_error'] = "비밀번호가 일치하지 않습니다.";
            header("location: registration.php");
            exit;
        }
    }
       
?>

 

 

4) vali_check.php:

유효성 검사 함수를 통해 참, 거짓 판별 -> 결과 regi_proc.php에 반환

<?php 

    function login_check1($regi_id,$exist_id) {

        return $regi_id !== $exist_id;   //값과 자료형이 모두 다르다

    }

    function login_check2($regi_pass,$regi_pass_ok) {
        
        return $regi_pass == $regi_pass_ok;
 
    }

?>

 

유효성 검사 결과이다. 하지만 이게 완성이 I need you? 이 글 쓰면서 발전하는 오류출력 화면이 되었습니다.

  • 로직

㉮   registration.php

폼에서 POST 방식으로 regi_proc.php에 데이터를 보냄

 

㉯  regi_proc.php

DB 연동, POST로 받은 데이터를 변수에 저장

SELECT 문으로 받은 id 값이 같은 행을 뽑아내서 vali_check.php에 유효성 검사 보냄

 

㉰  vali_check.php

유효성 검사 함수가 담긴 문서받은 id값과 DB에 이미 있는 id값을 비교         -> 같지 않으면 참, 같으면 거짓을 regi_proc.php로 반환받은 비밀번호 값과 비밀번호 확인 값을 비교          -> 같으면 참, 같지 않으면 거짓을 regi_proc.php로 반환

 

㉱  regi_proc.php

㉱ -1 (둘 다 일 경우) 

DB에 받은 데이터를 모두 INSERT하고 index.html로 리다이렉트㉱ -2 (둘 중 하나가 거짓일 경우) 세션 변수에 오류문 저장 후 registration.php로 리다이렉트

 

㉲  registration.php

세션 변수에 값이이 있으면 저장된 오류문을 변수에 할당 아이디만 중복되거나 아이디, 비번 둘 다 유효성 검사 통과하지 못했을 경우 -> 아이디 오류문 출력 (echo)비번만 검사에 통과하지 못했을 경우 -> 비번 오류문 출력 (echo)               =>  exit; 가 둘 다 붙어있어서 아이디 유효성 검사에서 거짓 나오면 무조건 아이디 오류문만 출력된다.                => 아이디 검사 부분의 exit를 지웠더니 둘 다 틀리면 두 오류문 모두 표기되었으나 굳이 바꿔야할까 싶기도 하다.                      (근데 일단 바꿈.)세션변수 초기화

 

유효성 검사에 통과할 데이터를 입력하는 모습이다.

 

유효성 검사에 통과하여 DB에 입력된 모습을 phpMyAdmin에서 캡쳐하였다.

 

 

 

+ 와씨 미친 저놈의 echo 꾸밀 수도 없고 맘에 안들었는데 고쳤다!!!!!!!! 으아!!!!!!! 와!!!!!!!!!!!!!

오류문 수정본. <span>태그 부분의 위치를 옮겼다. 왜 저건 안되고 왜 이건 된 걸까!? 변수 설정 과정에서 겪은 어려움과 연관되어 있을 것 같기도 하다. 아무튼 이걸 이해하면 컴퓨터놈이 데이터를 처리하는 방식을 조금은 알게 될 것 같다.

 

오류문 수정본 결과. 근데 이게 끝이 아니고 아래에서 한 번 더 수정됩니다.

 

 

 

 

  • 겪은 문제들

할 말이 많다.

 

가장 많이 겪은 문제의 원인은 단연

오타!!!!!!!!!

라고 할 수 있다.

 

 

그 외의 내가 겪은 문제의 원인들을 리스트해보자면..

  1. 오타
  2. 상수 정의 부분 작은 따옴표
  3. 쿼리문 결과를 변수에 저장할 때 mysqli_fetch_array($result['id'])로 표현
  4. 유효성 검사 통과 못 했을 때 로그인 페이지로 돌아가지 않는 것 (리다이렉트)
  5. 메서드명 틀림 (require_once 를 required_once로 알고 있었다.)
  6. 변수 초기화
  7. 경고문 출력 안됨 (이건 방금 해결했다.ㅎㅎ..)

대충 이정도로 정리할 수 있다.

 

 

아래 접은글은 오류가 났을 때 오타가 났는지 확인해야할 부분을 정리한 글이다.

오타가 발견될 때마다 적어두면 좋았을 것을..

더보기

쿼리가 동작을 안한다.

          => DB연동했으면 define부분 확인, db관련 변수 확인

 

  동작을 실행했는데 페이지가 안 넘어간다.

          => 리다이렉션 될 페이지 오타 확인

 

  변수 다르게 쓴 부분 있나 확인

 

  메서드명 제대로 썼나 확인

 

(어디서 잘못 됐는지 알기 위해서는 디버깅 코드를 잘 써먹을 줄 알아야 할 것 같다.)

(그리고 웬만하면 registration 이런 문자를 지양해야할 것 같다.)

 

 

추가로

   html이 포함된 php파일을 요청했는데 화면에 나타나지 않는다.

            => php는 오류출력 설정을 하지 않으면 그냥 하얀 화면에 멈추는 듯하다.

                  어떤 오류가 났는지 알 기 위해서는 에러 출력 코드를 사용하는 것이 좋을 것 같다.

 

아래는 php코드의 에러를 확인할 수 있는 코드이다.   

ini_set('display_errors', 1);  //에러를 브라우저 화면에 출력, 0은 출력 안함
ini_set('display_startup_errors', 1); //php 설정 초기화 시 발생하는 에러 출력, 0은 출력 안함
error_reporting(E_ALL); //php코드 에러를 포괄적인 수준에서 보고함

 

이 코드들 덕분에 변수 초기화 문제를 알 수 있었다.

 

 

아래는 regi_proc.php의 거의 초반 버전이다.

<html>

<?php
    define(DB_SERVER, 'localhost');
    define(DB_USER, '안알랴줌');
    define(DB_PASS, '안알랴줌222');
    define(DB_NAME, 'registration');

    $db_conn = mysqli_connect(DB_SERVER,DB_USER,DB_PASS,DB_NAME);

    /*if($db_conn) {
        echo "인증 오류";
    }*/

    $regi_id = $_POST['regi_id'];
    $regi_pass = $_POST['regi_pass'];
    $regi_pass_ok = $_POST['regi_pass_ok'];
    $email = $_POST['email'];
    $nick = $_POST['user-name'];
    $submit = $_POST['submit'];


    $sql_select = "SELECT * FROM registration_list WHERE id='$regi_id'";
    
    $select_result = mysqli_query($db_conn, $sql_select);

    $row = mysqli_fetch_array($result['id']);

    if ($regi_id == $row['id']) {
        echo "이미 사용 중인 아이디입니다.";
    }

    elseif ($regi_pass == $regi_pass_ok) {
        if ($submit) {

            $sql_insert = "INSERT INTO registration_list(idx,id,pass,email,nickname) values(null, '$regi_id','$regi_pass','$email','$nick')";

            $insert_result = mysqli_query($db_conn, $sql_insert);

            header("location: index.html");

        } else {
            echo "비밀번호가 일치하지 않습니다.";
        }
        if (!$insert_result==false) {
            echo "mysqli_error($db_conn)";
        }
        
    }            

?>

</html>

(과제를 어찌저찌 완료한 지금 봐도 왜 이렇게 썼지 싶은데 5개월 스터디를 채우고 나면 얼마나 어설퍼 보일까. 즐겁다 즐거워 와하하)

(근데 이거 왜 됐냐)

 

위의 코드의 경우 

1. 상수에 작은 따옴표가 안 붙어있음 -> 근데 이건 지금 작은 따옴표 떼고 실행해봤는데 되긴 함.

2. $result에서 데이터를 뽑아서 $row에 저장함 -> 내가 원하는 데이터가 아니라 속성으로 저장됐을 것. if문 비교 힘듦.

3. elseif는 뭐냐?

4. 유효성 검사 경고문을 새 페이지에 표시하고 싶은 거냐???

5. 왜 저렇게 했냐 말이 안되는데????

 

그런데 정말 신기하게도 몇가지 동작은 되었다.

 

1. 이미 있는 아이디를 써넣었거나

2. 비밀번호와 비밀번호 확인 박스에 넣은 값이 다를 경우 DB에 데이터가 insert되지 않았다.

 

아마 .... 캐시를 지웠으면 달랐을 수도 있고..

아니면 if문의 id 조건과 elseif문의 비밀번호 조건만 해석되어

'id가 중복되지 않는 것 중에 입력 비번이 일치하면 INSERT문이 실행'되었을 수도 있을 것 같다.

 

 

어찌 되었든 여기까진 의도했던 바였다. 하지만 난 그것만이 아니라

이미 사용 중인 아이디일 경우, 비밀번호 박스에 쓴 값과 비밀번호 확인 박스에 쓴 값이 서로 다를 경우에

submit 버튼을 누르면

각 박스 밑에 경고문구를 표시해주는 기능을 넣고 싶었다!!!!!!!

 

하지만 그것은 결코 쉬운 일이 아니었으니

아래가 그 이유와 해결한 방법이다.

(로직 수정은 생략함..)

 

 

 

1) 아이디가 중복되거나 비밀번호가 일치하지 않을 때

regi_proc.php 파일에서 멈춰버림

해당 케이스를 처리할 때 회원가입이 완료되지 않으면 다시 회원가입 페이지로 돌아가야 한다.

그런데 나는 유효성 검사 결과에 따라 INSERT문을 수행하도록 만든 regi_proc.php 파일에서 멈춰버린 것이다. 심지어 html 한 톨 없는 쌩 php 문서여서 아무것도 나오지 않았었다.

그래서 header메서드를 추가했다.

header("location: registration.php");

 

해당 함수는 HTTP 응답 헤더에 location, 도착지 부분을 표기하여

웹브라우저가 해당 페이지로 리다이렉트될 수 있게 한다.  (Burp Suite 이라는 프록시 툴을 사용하여 보여주셨다.)

 

그래서 저 코드를 추가하면 유효성 검사를 통과하지 못했을 때 회원가입 초기 화면이 나타나게 된다.

 

하지만 내가 원하는 것은 이게 전부가 아니었다!!

 

 

 

2) 회원가입 페이지로 돌아갔는데 

경고문이 안 나옴

당연하다. 뭘 출력해야할지 회원가입 페이지에서는 알 수 없기 때문이다.

그래서 찾은 것이 "세션 변수"였다. 

 

우선 이 과정에 기여하는 파일의 상단에 session(); 코드를 넣는다. 

나 세션 쓴다~ 라는 뜻인 듯하다.

 

그리고 유효성 검사의 결과를 받는 regi_proc.php 파일에 

   1) 아이디 유효성 검사가 틀리면~

                세션 변수에 "경고문"을 저장해~

                그리고 회원가입 페이지로 가~ 회원가입 폼 출력해~

   2) 비밀번호 유효성 검사가 틀리면~

                세션 변수에 "경고문"을 저장해~

                그리고 회원가입 페이지로 가~ 회원가입 폼 출력해~

라고 지시사항을 저장한다.

 

그러면 회원가입 페이지에서 그 세션 변수를 사용할 수 있다.

(세션은 3주차에 더 자세히 공부할 예정이다.)

 

아래는 세션을 추가한 수정한 회원가입 페이지이다.

<!DOCTYPE html>
<html>

<?php
    session_start();


    $id_error = "";
    $pw_error = "";

    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);


      /*  require_once('vali_check.php');*/
?>

    <head>         
        <link href="./regi_style.css" rel="stylesheet">
        <meta charset="UTF-8">
        <title>
            로그인 페이지
        </title>
    </head>


    <body>`
        <div class="logo">
            <img src="./img/logo.png"/>
        </div>
        <form method="POST" action="regi_proc.php">
            <div>
                <input type="text" name="regi_id" placeholder="아이디" class="regi-info"/>
            </div>
            <div>
                <input type="password" name="regi_pass" placeholder="비밀번호" class="regi-info"/>
            </div>
            <div>
                <input type="password" name="regi_pass_ok" placeholder="비밀번호 확인" class="regi-info"/>
            </div>
            <div>
                <input type="text" name="email" placeholder="이메일 주소" class="regi-info"/>
            </div>
            <div>
                <input type="text" name="user-name" placeholder="사용할 이름" class="regi-info"/>
            </div>
        
            <p style="color:red"><?php echo $id_error; ?></p>
            <p style="color:red"><?php echo $pw_error; ?></p>

                <?php
                    $id_error = $_SESSION['id_error'];
                    $pw_error = $_SESSION['pw_error'];

                    /*$id_error = isset($_SESSION['id_error'])? $_SESSION['id_error'] : "";
                    $pw_error = isset($_SESSION['pw_error'])? $_SESSION['pw_error'] : "";*/

                    echo $pw_error;
                    echo $id_error;


                    unset($_SESSION['id_error']);
                    unset($_SESSION['pw_error']);
                                    
                ?>
            <div>
                <input type="submit" name="submit" value="가입하기" class="button"/>
            </div>

        </form>

    </body>

</html>

세션 변수로 받은 값을 registration.php 파일의 변수에 저장하고 있다.

저장한 오류문을 출력하고 세션변수를 다시 초기화하고 있다.

(초기화하지 않으면 새로운 페이지에서 접근해도 오류문이 남아있다.)

 

주석처리된 부분은 세션변수를 삼항식으로 저장하는 방법이다. 세션변수에 값이 있으면 세션변수를 저장하고 없으면 공백으로 둔다.

이거로 해도 돌아가고 저거로 해도 돌아가는데 삼항식이 더 확실한 느낌이긴 하다.

아무튼 이런 방식으로 입력 폼 바로 밑에 echo로 출력시킨게 어제까지의 결과이다.

 

하지만 이것 또한 내 의도와는 달랐다.

 

경고문이라 하면 흔히들 떠올리는 것은 빨간색이 아닌가. 저 결과도 구현되었을 당시엔 정말 기뻤지만 하나가 되면 이것도 해보고 싶고, 저것도 해보고 싶은 게 인간의 욕심이 아닌가.하지만 저 <span>태그 부분을 이동시키면 결과는 출력되지 않았다.

 

 

 

그래서 찾은 방법이 아래처럼 php코드 사이에 끼워넣는 방법이었다.

이 방법 또한 경고문의 위치를 옮길 수는 없었다.

 

 

 

방금 찾은 방법이 아래처럼 변수에 저장하지 않고 직접적으로 세션변수를 출력하는 방법이다.

<span style='color: red'><?=isset($_SESSION['id_error'])? $_SESSION['id_error'] : "";?></span>

이 방법으로 했을 때 비로소 아이디 인풋박스와 비밀번호 확인 인풋박스 밑에 경고문이 나타나도록 할 수 있었다.

(하는 김에 글씨도 bold 처리 했다.)

 

증거 사진 제출합니다.

 

 

아래는 변수 사용에 대한 나의 어설픈 고찰이다. 꽤 긺. 세 줄 요약 있음

더보기

위 과정을 통해 변수는 어째서 쓰는 것일까.. 라는 생각을 하게 되었다.

 

물론 사용하는 이유 중 가장 큰 부분을 차지하는 게 긴 글 여러번 쓰지 않아도 된다는 점임을 알고 있다.

그니까 내가 초점을 맞춰야 할 부분은 왜 오류가 난 것일까 하는 점일 테다.

 

난 두가지 요소가 오류의 원인일 것이라 생각하고 있다.

 

1. 변수 초기화 위치

2. 변수가 쓰이는 위치

 

우선 내가 위에서 쓰지 않았던 어려움을 여기서 써야할 것 같다. 

세션 변수에 삼항식을 이용하여 직접적으로 쓰기 전에 난 삼항식으로 나온 세션 변수 값을 $id_error 등과 같은 php 변수에 저장했었다.

 

그때 자주 마주친 php오류문이 있었는데 그게 모두 변수가 정의되지 않았다, 초기화되지 않았다는 뜻이라는 걸 알게 되었다. 난 분명 선언과 동시에 값을 할당 했는데 말이지...

 

변수 초기화의 필요성에 대한 고찰

 

POST로 받은 데이터를 저장할 변수는 미리 초기화하지 않아도 되었고 외부에 있는 함수로 유효성 검사에 대한 참, 거짓 결과를 받을 때도 변수의 초기화를 따로 해야하는 일은 없었다.

 

그니까 아마 세션 변수를 사용했기 때문에 이같은 오류를 마주쳤던 것 같다. 세션 변수만의 어떤 특징 때문에!

다른 건 선언과 동시에 데이터 할당이 가능한데, 세션 변수를 사용한 저 삼항식은 뭔가.. 그.. 처리가 늦나?

 

POST로 보내기 전에도 php 코드에선 $id_error와 같은 변수가 읽히긴 하는데

거기에 값을 할당할 수 있는 시점이 regi_proc.php 에서 세션 변수를 받아온 후이기 때문에

맨 처음 정적 페이지를 만들어 서버에 보낼 때 변수명만 덩그러니 남은 상태가 되어 오류문이 뜨는 것 같다.

(세션 변수가 문제인 게 아니라 삼항식이 문제인 것)

 

음, 말이 되는군. 이제 변수 초기화의 필요성은 인지를 한 상태이다.

그렇다면 변수를 초기화하는 코드의 위치는 어떤 영향을 줄까?

 

변수 초기화의 위치에 대한 고찰

 

회원가입 페이지가 대략 아래와 같은 구조였다고 한다면

[세션 시작]

[html코드]

[php 코드]

 

$id_error = isset($_SESSION['id_error'])? $_SESSION['id_error']: "" ;

위의 삼항식 결과를 변수에 저장하는 코드가 [php코드] 위치에 있었다.

이 상태에서 php 변수를 초기화 하는 $id_error="";와 같은 코드의 위치만 옮겼었다.

 

1)  [php 코드] 위치의 삼항식 코드 바로 위.

경고문 잘 출력됨.

 

 

2)  [세션 시작] 위치

경고문 잘 출력됨.

어쩌면 단순히 세션변수가 php 변수에 할당되기 전에 나 이 변수 쓸 거다~ 라고 미리 말해둬야 하는 문제일지도 모른다.

그럼 

 

 

3)  [php 코드] 위치의 삼항식 코드 바로 아래

(코드 순서: 세션변수 값을 php변수에 할당 -> 변수 초기화 -> 오류문 출력)

경고문 안 나옴.

 

하지만 변수가 정의되지 않았다는 php 경고문은 나오지 않았다.

또한 echo "this is".$id_error; 코드를 추가하여 변수에 값이 할당되는지 확인한 결과 값은 할당 되었다.

 

즉, 값이 저장된 후 출력되는 과정에서 문제가 발생했다는 뜻일 테다.

<span style='color:red'><?= $id_error?></span> 이 코드 자체의 문제는 아닐 것이다. 다른 경우에서도 똑같은 형태로 썼기 때문이다. 

 

아 삼항식으로 세션변수 값을 php 변수에 할당하고 초기화해버리는 건가....?

그래서 출력하자니 값이 없어 못하는 거고......... 헐..

 

 

4)  [php코드] 위치의 <span>태그로 감싼 echo $id_error; 바로 아래

잘 됨. 새로고침 했을 때, 페이지 새로 열었을 때 경고문 사라짐. 잘 된다는 뜻임.

 

위와 같이 초기화 코드의 위치에 따라 원하는 기능이 구현되기도 하고 안되기도 한다.

 

하지만 변수를 초기화한 위치 자체만으로는 잘 파악이 안된다.

어쩌면 변수가 쓰이는 위치와의 연관되어 있을지도 모르겠다.

 

 

아놔 그럼 $id_error 변수가 어디 쓰이든 세션변수 값 할당된 후에 초기화만 안하면 되겠네?

 

근데 또 그렇게 호락호락하지가 않았다.

세션 변수가 할당된 php변수의 위치에 따라 오류문이 출력되지 않았기 때문이다.

 

php 변수가 쓰이는 위치

 

다시 해당 파일의 구조를 가져왔다.

[세션 시작]

[html코드]

[php 코드]

 

내가 처음 경고문 출력을 사용했던 위치는 html코드의 input태그 바로 아래였다.

변수 초기화 코드는 세션 시작 부분에 있었다면 변수 할당 과정은 php코드 부분에 있었다.

(변수 초기화 - 오류 출력 - 세션변수를 php 변수에 할당 순서)

이땐 내가 만든 경고문이 출력되지 않았다. 

 

아까는 왜인지 알 수 없었지만 이젠 알 것같다.

1. 첫번째로 파일을 쫘악 훑을 때 변수 확인하고, post로 데이터를 보낸다.

2. 데이터를 받은 파일에서 유효성 검사를 하고 결과를 세션변수에 저장, 회원가입 페이지로 리다이렉션.

3. 세션변수가 쓰인 부분 확인하고 코드 진행(php변수에 할당)

4. 그 아래로 그 변수가 안 쓰이면 어떤 실행도 없이 걍 지나감.

 

그 증거로 코드 순서를 바꿨더니 오류문이 제대로 출력되었다. 코드 자체는 고치지 않았다.

[세션 시작]: 변수 초기화 - 세션변수를 php 변수에 할당

[html코드]: 오류 출력 <span>태그

[php코드]: 세션변수 초기화

 

아래는 [세션 시작] 부분의 최종 코드이다.

<?php
    session_start();

    $id_error = $_SESSION['id_error'];
    $pw_error = $_SESSION['pw_error'];

    unset($_SESSION['id_error']);
    unset($_SESSION['pw_error']);

    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

?>

 

결론

 

여기서 내가 도출한 결론은 php는 빠구없는 애라는 것이다.

어 세션변수 썼어? 그럼 거기서부터 시작해. 위에 뭐가 쓰였대? 어쩔termius.

동적 페이지 처리라고 마냥 부지런하지는 않은가보다.

 

 

그래서 차라리 php변수에 할당하는 과정을 생략하고

세션 변수에 삼항식을 둬서 오류문 출력하게 하는 방식이 더 깔끔할지도 모르겠다.

 

(<span>태그 부분을 <?= isset($_SESSION['id_error'])? $_SESSION['id_error'] : "" ; ?> 이런 식으로 변수에 할당하지 않고 직접적으로 출력하게 했더니 됐다....)

 

3줄 요약

 

1. 삼항식으로 변수를 할당할 거면 해당 변수를 초기화하자.

2. 변수 초기화는 출력한 다음에 하도록 하자.

3. 세션변수 값을 php 변수에 할당해서 쓸 거면 파일 위쪽에다 쓰자.

 

 

정리하고 나니 컴퓨터를 이해한 건지 php 인터프리터를 이해한 건지 모르겠다.

이런 경험이 쌓이다보면 컴퓨터를 이해하게 되겠지..

 

 

 

♨ 로그인 페이지 DB 연동시키기

 

파일은 총 3개가 만들어졌다.

 

1) login.html : 

2) loginstyle.css

3) login.php

였던 것들인데 방금 수정됨.

 

방금 어떤 일이 있었냐면 회원가입 페이지에서 배운거 써먹으려고 수정 중인데

세션을 쓰려면 login.html이 php 파일이 되어야해서 아무 생각 없이 수정했더니

기존에 있던 login.php 위에 덧씌워졌다. 그렇다. 내 php 코드는 다 날아간 것이다.

그래서 방금 다시 씀. 실수란 실수는 다 하는구나 장하다 myselft.

 

현재 파일 3개

 

1) login.php : 폼에서 ID, 비밀번호 값 받고 POST 방식으로 login_proc.php 파일에 전달

2) loginstyle.css : 로그인 페이지의 디자인

3) login_proc.php : POST로 전달받은 데이터를 DB에 저장된 데이터와 비교 후 로그인 처리

 

 

  • 2주차 완성본

1) login.php

내 사이트 대문
오류 시 화면. css 저거 어떡하냐 진짜.

 

<?php 
    session_start();

    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
?>

<!DOCTYPE html>
<html>
    <head>
        <link href="./loginstyle.css" rel="stylesheet">
        <meta charset="UTF-8">
        <title>
            로그인 페이지
        </title>
    </head>

    <body>
        <div class="logo">
            <img src="./img/logo.png"/>
        </div>
         
                <form method="post" action="login_proc.php">
                    <br><br>
                    <div class="input">
                        <div class="main-content">
                            <input type="text" name="id" placeholder="아이디" class="main-content"/>
                        </div>                       
                        <div class="main-content">
                            <input type="password" name="passwd" placeholder="비밀번호"/>
                        </div>
                        <div>
                            <input type="submit" value="로그인" class="button"/>
                        </div>
                    </div>    
                    <br><span style='color:red' class="login_error"><?=isset($_SESSION['login_error'])? $_SESSION['login_error']:"";?></span>
                    <?php unset($_SESSION['login_error']);?>
                        <footer>
                            <hr>
                            <a href="#">X로 로그인하기</a>
                            <a href="./registration.php" target="_blank">회원가입</a>
                            <hr>
                        </footer>    
                </form>            
    </body>
</html>

 

 

 

2) loginstyle.css

* {
    font-family: Arial, Helvetica, sans-serif;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    text-align: center;
}

body {
    display: flex;
    flex-direction: column; /* 로고가 위, 콘텐츠가 아래로 배치 */
    justify-content: center;
    align-items: center;
    height: 100vh;
    background-color: rgb(255, 255, 255);
    padding: 20px;
    transform: scale(1.15);
    overflow: hidden;
}

.logo {
    text-align: center;
    margin-bottom: 40px; /* 로고 아래 여백 */
}

.logo img {
    width: 65%; /* 로고 크기 */
}


form {
    display: flex;
    flex-direction: column;
    padding: 20px;
    margin-right: 100px;
    border-radius: 10px;
    width: 300px;
    height: 467px;

    background-image: url("./img/login_back.png");
    background-size: 100%;
    background-repeat: no-repeat;
}

form .main-content {
    margin-top: 10px;
    /*margin-left: 20px;*/
    height: 40px;
}

form .main-content input {
    margin-bottom: 15px;
    padding: 10px;
    font-size: 16px;
    width: 65%;
    align-items: center;
    height: 40px;
    margin: 15px;
    justify-content: center;
}

.button {
    font-size: 16px;
    justify-content: center;
    align-items: center;
    width: 65%;
    height: 40px;
    margin: 40px;
    padding: 10px;
    background-color: rgb(219, 217, 215);
}

.button:hover {
    background-color: rgb(240,130,0);
}

.login_error {
    font-weight: bold;
}

 

 

 

3) login_proc.php

<?php 

session_start();

define('DB_SERVER', 'localhost');
define('DB_USER', '안알랴줌');
define('DB_PASS', '안알랴줌222');
define('DB_NAME', 'registration');

$db_conn = mysqli_connect(DB_SERVER,DB_USER,DB_PASS,DB_NAME);

if($db_conn) {
    echo "인증 오류";
} //디버깅 코드

$id = $_POST['id'];
$pw = $_POST['passwd'];

$select_sql = "SELECT * FROM registration_list WHERE id='$id'";

$result = mysqli_query($db_conn,$select_sql);

$row = mysqli_fetch_array($result);

$user_id = $row['id'];
$user_pw = $row['pass'];


if($id==$user_id && $pw==$user_pw) {
    header("location: index.html");
    exit;
} else {
    $_SESSION['login_error'] = "아이디 또는 비밀번호가 일치하지 않습니다.";
    header("location: login.php");
    exit;
}

?>

 

 

 

  • 로직

㉮  login.php

사용자가 폼의 input박스에 넣은 데이터를 POST 방식으로 login_proc.php 파일에 전달

 

㉯  login_proc.php

DB 연동, POST로 받은 값을 변수에 저장SELECT문으로 해당 아이디를 가진 행의 데이터 추출    데이터가 있으면 index.html로    데이터가 없으면 세션변수(오류문) 가지고 login.php로

 

㉰ login.php회원 정보가 없을 경우 오류문 출력

 

별거 없어 보이지만 3주차에 이 로그인 페이지에서 별 거 다 할테니 아쉬워할 수 없다.

 

 

 

  • 겪은 문제들

파일이 날아갔다.

 

그거 말고는 회원가입 처리를 구현할 때보다 어려운 점은 없었다.

여기서도 처음부터 유효성 검사를 넣으려고 했다면 괴로웠겠지만 처음엔 데이터가 없으면 로그인 초기 화면으로 돌아갔다.

 

아 노트를 보니까 위에 회원가입 처리에 대해 쓸 때 이미 다 적어버렸다.

 

1. define함수에서 상수에 작은따옴표를 써야한다.

2. mysqli_fetch_array로 결과 값 뽑을 땐 컬럼명 안 쓴다.

 

이 두개에 대해 적혀 있다.

 

이에 대해 생각해볼만한 것은

mysqli 함수일 것 같다.쿼리 결과에서 행을 뽑는데 mysqli_fetch_array도 있지만 여러가지가 있는 듯 하다.

그 뭐여 escape 뭐시기 그런 것도 있는 것 같고..

 

3주차에서는 저 행 뽑는 함수랑

로그인, 회원가입 기능을 보완할 예정이다. 지금 폼에 아무것도 안 쓰고 제출해도 index.html로 넘어가서.. 그거 고쳐야지...

그리고 가장 중요한 세션, 쿠키, 세션ID의 개념에 대해 익히고 비밀번호 해싱처리도 실습할 예정이다.