Almon Dev

쿠키로 로그인 구현하기 (모의해킹 공부) 본문

모의해킹/웹 개발

쿠키로 로그인 구현하기 (모의해킹 공부)

Almon 2024. 10. 31. 21:35

쿠키(Cookie)로 로그인 구현하기

 

인덱스 페이지

index.php

<?php
if (isset($_COOKIE['user_id'])){
    header("Location: login_successful.php");
    exit;
}else {
    header("Location: login2.php");
}
?>

 

if (isset($_COOKIE['user_id'])){

isset() 함수를 이용해서 요청에 같이 온 쿠키 중에 user_id라는 이름의 값이 세팅되어 있는지 확인합니다.

 

    header("Location: login_successful.php");
    exit;

쿠키가 존재한다면 프로필 페이지로 리다이렉션 시킵니다. exit를 이용해서 코드를 바로 종료합니다.

 

}else {
    header("Location: login2.php");
}

만일 쿠키가 없다면 로그인 페이지로 리다이렉션 시킵니다.


로그인 페이지

login2.php

<?php
    if(isset($_COOKIE['user_id'])) {
        header("Location: login_successful.php");
        exit;
    }
?>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Almond Login</title>
    <link rel="stylesheet" href="/css/login2.css">
</head>
<body>
    <container class="login-container">
        <form class="login-form" action="login_proc2.php" method="post">
            <div class="logo-container">
                <a href="/login2.php"><img src="/imgs/almond.png" alt="logo" class="logo"></a>
            </div>
            <h2>Almond</h2>
            <input type="text" class="login-input" name="id" placeholder="아이디 또는 전화번호" required>
            <input type="password" class="login-input" name="passwd" placeholder="비밀번호" required>
            <?php
            if (isset($_GET['result'])) {
                $result = $_GET['result'];
                if ($result == "failed") {
                    echo '<p class="login-failed">로그인에 실패하셨습니다.</p>';
                }
            }
            ?>
            <button type="submit" class="login-submit">로그인</button>
        </form>
    </container>
    <div class="login-more">
        <a href="#">아이디 찾기</a>
        <a href="#">비밀번호 찾기</a>
        <a href="sign_up.php">회원가입</a>
    </div>
    <footer>
        <a href="https://www.flaticon.com/kr/free-icons/" title=" 아이콘" class="logo-source"> 아이콘 제작자: Freepik - Flaticon</a>
    </footer>
</body>
</html>

 

<?php
    if(isset($_COOKIE['user_id'])) {
        header("Location: login_successful.php");
        exit;
    }
?>

쿠키가 있을 때 프로필 페이지로 리다이렉션 시키는 코드를 추가했습니다.

exit를 추가해서 이동시 아랫부분의 html코드가 전송되지 않게 했습니다.

 

login_proc2.php

수정 전

<?php
    include("mysql.php");

    $id = $_POST["id"];
    $pass = $_POST["passwd"];
    $url = '/login_successful.php';
    $sql = "select nickname from users where id='$id' and password='$pass';";

    $sql_result = runSQL($sql);

    // $result = false;

    if ($row = mysqli_fetch_array($sql_result)) {
        $nick = $row['nickname'];
        $update_sql = "update users set login=1 where nickname='$nick';";
        runSQL($update_sql);

        echo "<form id='redirection-form' action='$url' method='post'>";
        echo "<input type='hidden' name='nickname' value='$nick'>";
        echo "</form>";
        echo "<script>document.getElementById('redirection-form').submit()</script>";
        exit;
    }
    
    header('Location: login2.php?result=failed');
?>

 

수정 후

<?php
    include("mysql.php");
    
    
    $id = $_POST["id"];
    $pass = $_POST["passwd"];
    $url = '/login_successful.php';
    $sql = "select nickname from users where id='$id' and password='$pass';";
    
    $sql_result = runSQL($sql);
    
    // $result = false;
    
    if ($row = mysqli_fetch_array($sql_result)) {
        $nick = $row['nickname'];
        $update_sql = "update users set login=1 where nickname='$nick';";
        runSQL($update_sql);

        // setcookie("user_id", $id, 0, "/");
        setcookie("user_id", $id, time()+ 60*60*24,"/");
        header("location:$url");
        
        // echo "<form id='redirection-form' action='$url' method='get'>";
        // echo "<input type='hidden' name='nickname' value='$nick'>";
        // echo "</form>";
        // echo "<script>document.getElementById('redirection-form').submit()</script>";
        exit;
    }
    
    header('Location: login2.php?result=failed');
?>

 

추가된 부분

        setcookie("user_id", $id, time()+ 60*60*24,"/");
        header("location:$url");

로그인 성공 시 setcookie() 함수를 이용해서 user_id라는 이름과 $id값을 가진 쿠키를 생성합니다.

time() 함수는 현재 시간을 60*60*24는 하루를 의미합니다.

header를 이용해서 프로필 페이지로 리다이렉션을 시킵니다.


프로필 페이지

login_successful.php

수정 전

<?php 
    $nickname = $_POST['nickname'];
?>

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Almond</title>
    <link rel="stylesheet" href="/css/login_successful.css">
    <script src="./script/logout.js" defer></script>
</head>
<body>
    <container class="profile-container">
        <div class="profile">
            <img src="/imgs/almond-profile.jpg" class="profile_img">
            <div class="profile_info">
                <h2 class="profile_name"><?php echo $nickname; ?></h2>
                <p class="profile_subs">구독자 <strong>0명</strong></p>
            </div>
        </div>
        
        <div class="profile_link">
            <a href="#" class="link_tab"><p>글쓰기</p></a>
            <a href="#" class="link_tab"><p>마이페이지</p></a>
            <?php
                printf('<button class="link_tab logout-btn" onclick=\'logout("%s")\'>로그아웃</button>', $nickname);
            ?>
        </div>
    </container>
</body>
</html>

 

수정 후

<?php 
// $nickname = $_GET['nickname'];
$nickname = "";
if(isset($_COOKIE["user_id"])) {
    require_once("mysql.php");
    $user_id = $_COOKIE["user_id"];
    $sql = "select nickname from users where id='$user_id'";
    $nickname = runSQL($sql)->fetch_array()['nickname'];
}else {
    header("location: login2.php");
    exit;
}
?>

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Almond</title>
    <link rel="stylesheet" href="/css/login_successful.css">
    <script src="./script/logout.js" defer></script>
    <script src="./script/mypage.js" defer></script>
</head>
<body>
    <container class="profile-container">
        <div class="profile">
            <img src="/imgs/almond-profile.jpg" class="profile_img">
            <div class="profile_info">
                <h2 class="profile_name"><?= $nickname; ?></h2>
                <p class="profile_subs">구독자 <strong>0명</strong></p>
            </div>
        </div>
        
        <div class="profile_link">
            <a href="#" class="link_tab"><p>글쓰기</p></a>
            <!-- <a href="mypage.php" class="link_tab"><p>마이페이지</p></a> -->
            <?php
                printf('<button class="link_tab mypage-btn" onclick=\'mypage("%s")\'>마이페이지</button>', $nickname);
            ?>
            <a href="logout.php" class="link_tab"><p>로그아웃</p></a>
        </div>
        <div class="content"></div>
        <button class="mypageset-btn">수정하기</button>
    </container>
</body>
</html>

 

추가된 부분

<?php 
$nickname = "";
if(isset($_COOKIE["user_id"])) {
    require_once("mysql.php");
    $user_id = $_COOKIE["user_id"];
    $sql = "select nickname from users where id='$user_id'";
    $nickname = runSQL($sql)->fetch_array()['nickname'];
}else {
    header("location: login2.php");
    exit;
}
?>

 

if(isset($_COOKIE["user_id"])) {

isset을 이용해서 user_id 이름을 가진 쿠키가 있는지 확인합니다.

 

require_once("mysql.php");

쿼리문을 실행하기 위해서 runSQL함수가 있는 mysql.php파일을 포함합니다.

 

    $user_id = $_COOKIE["user_id"];
    $sql = "select nickname from users where id='$user_id'";

$user_id변수에 쿠키의 값을 넣고 $sql에 닉네임을 찾아오는 쿼리문을 작성합니다.

 

    $nickname = runSQL($sql)->fetch_array()['nickname'];

$nickname변수에 데이터베이스에서 가져온 닉네임을 대입합니다.

 

}else {
    header("location: login2.php");
    exit;

만약 쿠키가 없는 경우 로그인페이지로 리다이렉션을 시키고 exit를 이용해 코드를 종료합니다.

 

<a href="logout.php" class="link_tab"><p>로그아웃</p></a>

logout.js로 이동시키던 버튼을 삭제하고 logout.php로 바로 이동합니다.


로그아웃

logout.js

function logout(nickname) {
  console.log(nickname);

  fetch('/logout.php', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
    },
    body: JSON.stringify({
      nickname: nickname,
    }),
  })
    .then((res) => res.json())
    .then((res) => {
      if (res.result) {
        window.location.href = res.url;
      }
    });
}

logout.js는 삭제했습니다.

 

logout.php

수정 전

<?php
    include("mysql.php");
    $result = true;
    $nick = json_decode(file_get_contents("php://input"), true)['nickname'];
    // echo "$nick";
    $sql = "update users set login=0 where nickname='$nick';";

    $sql_result = runSQL($sql);

    header("Content-Type: application/json");
    echo json_encode(["url" => "/login2.php", "result" => $result]);
?>

 

수정 후

<?php
    include("mysql.php");
    if (isset($_COOKIE['user_id'])){
        $user_id = $_COOKIE['user_id'];
        $sql = "update users set login=0 where id='$user_id';";
        $sql_result = runSQL($sql);
        setcookie("user_id", "", time() - 60*60 ,"/");
    }
    header("Location: login2.php");
?>

 

    if (isset($_COOKIE['user_id'])){

user_id 쿠키가 있는지 확인합니다.

 

        $user_id = $_COOKIE['user_id'];
        $sql = "update users set login=0 where id='$user_id';";

$user_id 변수에 값을 넣고 $sql에 update문을 이용해서 로그인 컬럼을 0(로그아웃 상태)으로 수정합니다.

 

        setcookie("user_id", "", time() - 60*60 ,"/");

setcookie 함수로 user_id쿠키의 만료날짜를 1시간 전으로 수정해 삭제합니다.

 

    header("Location: login2.php");

쿠키를 삭제 완료하거나, 쿠키가 없는 경우 Location 헤더를 이용해서 로그인 페이지로 리다이렉션 시킵니다.


사진과 영상

 

 

쿠키 변조

 

 

쿠키는 클라이언트에 저장되는 정보이기 때문에 유저가 쉽게 수정할 수 있기 때문에 
쿠키로만 로그인을 구현할 경우 변조가 쉽게 가능합니다.

내일은 세션으로 쿠키의 문제를 해결해보려고 합니다.