보안을 그리다, 훈이

[Web Hacking / PHP & MySQL] 게시판 구현 - login.php / login_action.php 본문

Programming/PHP & MySQL

[Web Hacking / PHP & MySQL] 게시판 구현 - login.php / login_action.php

HooNeee 2021. 5. 2. 20:37

이번에는 대부분의 웹사이트에서 기본적으로 사용되는 로그인 서비스를 구현해보았다.

로그인을 통해 사용자를 식별하고 개별적으로 권한을 부여할 수 있기 때문에 게시판 관리의 효율성이 증진된다고 생각한다.

 

본 게시판에서는 회원에게만 글을 작성할 수 있는 권한을 부여하려고 한다.

먼저 사용자로 하여금 로그인 페이지인 login.php에 접근할 수 있도록 하기 위해 index.php 상단에 로그인 버튼을 제공한다.

ㅇㅇㅇㅇ

 

[index.php 수정 및 추가 소스코드]

<?php
    $connect = mysqli_connect('127.0.0.1', 'root', 'password', 'db_board') or die("connect failed");
    $query = "select * from board order by number desc";    //역순 출력
    $result = mysqli_query($connect, $query);
    // $result = $connect->query($query);
    $total = mysqli_num_rows($result);  //result set의 총 레코드(행) 수 반환

    session_start();

    if (isset($_SESSION['userid'])) {
    ?><b><?php echo $_SESSION['userid']; ?></b>님 반갑습니다.
        <button onclick="location.href='./logout_action.php'" style="float:right; font-size:15.5px;">로그아웃</button>
        <br />
    <?php
    } else {
    ?>
        <button onclick="location.href='./login.php'" style="float:right; font-size:15.5px;">로그인</button>
        <br />
    <?php
    }
    ?>

 

위 소스코드를 index.php의 body 태그 내 상단부분에 작성하였다.

 

세션 관리를 위해 session_start() 함수로 시작하고 세션이 존재하면 상단 좌측에 '[userid]님 반갑습니다.', 우측에 로그아웃 버튼을 제공한다.

세션이 존재하지 않으면 상단 우측에 login.php 페이지로 접근하는 로그인 버튼을 제공한다.

(index.php의 최종 소스코드와 결과는 본 포스팅 하단에 작성하도록 하겠다.)


다음으로 사용자가 실제로 로그인하는 페이지인 login.php를 구현하였다.

 

 

[login.php]

<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8'>
</head>

<body>
    <div align='center'>
        <span>
            <p style="font-size: 25px;"><b>로그인</b></p>
        </span>

        <form method='post' action='login_action.php'>
            <p><b>I &nbsp;D &nbsp;</b><input name="id" type="text"></p>
            <p><b>PW &nbsp;</b><input name="pw" type="password"></p>
            <br />&nbsp;
            <input type="submit" value="로그인">&nbsp;&nbsp;
        </form><br />
        <button id="register" onclick="location.href='./register.php'">회원가입</button>

    </div>
</body>

</html>

 

 

[login.php 결과]

로그인 버튼과 회원가입 버튼이 주어지며, 회원가입 버튼은 다음 포스팅에서 다룰 예정이다.

 

당연히 GET 방식이 아닌 POST 방식으로 login_action.php에 아이디와 비밀번호를 넘겨주어 인증을 처리하도록 하였다.


[login_action.php 소스코드]

<?php
session_start();

$connect = mysqli_connect("127.0.0.1", "root", "password", "db_board") or die("connect failed");

//입력 받은 id와 password
$id = $_POST['id'];
$pw = $_POST['pw'];

//아이디가 있는지 검사
$query = "select * from member where id='$id'";
$result = $connect->query($query);


//아이디가 있다면 비밀번호 검사
if (mysqli_num_rows($result) == 1) {

    $row = mysqli_fetch_assoc($result);

    //비밀번호가 맞다면 세션 생성
    if ($row['password'] == $pw) {    //password 평문비교 취약!
        $_SESSION['userid'] = $id;
        if (isset($_SESSION['userid'])) {
?> <script>
                location.replace("./index.php");
            </script>
        <?php
        } else {
            echo "session failed";
        }
    } else {
        ?> <script>
            alert("아이디 또는 비밀번호를 확인해주세요.");
            history.back(); //js 이 전페이지(login.php)로 돌아가기
        </script>
    <?php
    }
} else {
    ?> <script>
        alert("아이디 또는 비밀번호를 확인해주세요.");
        history.back();
    </script>
<?php
}
?>

 

index.php와 마찬가지로 session_start() 함수를 사용하여 세션을 시작한다.

 

login.php 폼에서 받아온 id가 db_board 데이터베이스의 member 테이블에 존재한다면 password를 비교하여 맞다면 세션을 생성하고 index.php로 돌아간다.

비밀번호를 DB에 평문으로 저장하는 것과 더불어 입력된 비밀번호를 평문으로 비교하는 방식 또한 매우 취약한 방식이니 주의하도록 하자!

필자는 추후에 수정할 계획이다.

 

 

[login_action.php 로그인 실패 결과]

아이디 또는 비밀번호가 일치하지 않다면 경고 창을 띄우고 history.back() 함수를 통해 다시 'login.php'로 돌아간다.


[index.php 소스코드]

<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8'>
    <style>
        table {
            border-top: 1px solid #444444;
            border-collapse: collapse;
        }

        tr {
            border-bottom: 1px solid #444444;
            padding: 10px;
        }

        td {
            border-bottom: 1px solid #efefef;
            padding: 10px;
        }

        table .even {
            background: #efefef;
        }

        .text {
            text-align: center;
            padding-top: 20px;
            color: #000000
        }

        .text:hover {
            text-decoration: underline;
        }

        a:link {
            color: #57A0EE;
            text-decoration: none;
        }

        a:hover {
            text-decoration: underline;
        }
    </style>
</head>

<body>
    <?php
    $connect = mysqli_connect('127.0.0.1', 'root', 'password', 'db_board') or die("connect failed");
    $query = "select * from board order by number desc";    //역순 출력
    $result = mysqli_query($connect, $query);
    // $result = $connect->query($query);
    $total = mysqli_num_rows($result);  //result set의 총 레코드(행) 수 반환

    session_start();

    if (isset($_SESSION['userid'])) {
    ?><b><?php echo $_SESSION['userid']; ?></b>님 반갑습니다.
        <button onclick="location.href='./logout_action.php'" style="float:right; font-size:15.5px;">로그아웃</button>
        <br />
    <?php
    } else {
    ?>
        <button onclick="location.href='./login.php'" style="float:right; font-size:15.5px;">로그인</button>
        <br />
    <?php
    }
    ?>

    <p style="font-size:25px; text-align:center"><b>게시판</b></p>

    <table align=center>
        <thead align="center">
            <tr>
                <td width="50" align="center">번호</td>
                <td width="500" align="center">제목</td>
                <td width="100" align="center">작성자</td>
                <td width="200" align="center">날짜</td>
                <td width="50" align="center">조회수</td>
            </tr>
        </thead>

        <tbody>
            <?php
            while ($rows = mysqli_fetch_assoc($result)) {   //result set에서 레코드(행)를 1개씩 리턴
                if ($total % 2 == 0) {
            ?>
                    <tr class="even">
                        <!--배경색 진하게-->
                    <?php } else {
                    ?>
                    <tr>
                        <!--배경색 그냥-->
                    <?php } ?>
                    <td width="50" align="center"><?php echo $total ?></td>
                    <td width="500" align="center">
                        <a href="read.php?number=<?php echo $rows['number'] ?>">
                            <?php echo $rows['title'] ?>
                    </td>
                    <td width="100" align="center"><?php echo $rows['id'] ?></td>
                    <td width="200" align="center"><?php echo $rows['date'] ?></td>
                    <td width="50" align="center"><?php echo $rows['hit'] ?></td>
                    </tr>
                <?php
                $total--;
            }
                ?>
        </tbody>
    </table>

    <div class=text>
        <font style="cursor: hand" onClick="location.href='./write.php'">글쓰기</font>
    </div>
</body>

</html>

 

 

[index.php 결과]

다음 포스팅에서는 회원가입 기능을 제공하는 register.php / register_action.php를 다룰 예정이다.

 

끝ㅌㅌㅌㅌㅌㅌㅌㅌㅌㅌ!!!!!!!!

Comments