Almon Dev

세션으로 로그인 구현하기(모의해킹 공부) 본문

모의해킹/웹 개발

세션으로 로그인 구현하기(모의해킹 공부)

Almon 2024. 11. 1. 20:05

세션(Session)으로 로그인 구현하기

 

인덱스 페이지

index.php

수정 전

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

 

수정 후

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

 

session_start();

사용자의 쿠키에 세션 ID가 있는지 확인하고, 없으면 세션 ID를 생성해 사용자의 쿠키에 저장합니다.

세션 ID가 있는 경우 세션 ID와 일치하는 파일을 찾아서 내용을 읽어 $_SESSION 배열에 저장합니다.

 

if (isset($_SESSION["user_id"])) {
    header("Location: login_successful.php");
    exit;

세션에 user_id가 있는 경우 프로필 페이지로 이동합니다.

 

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

세션에 user_id가 없는 경우 로그인 페이지로 이동합니다.

 

 

 

세션 파일은 서버에 PHPSESSID와 동일한 이름으로 저장됩니다.
세션 파일이 저장되는 위치는 php.ini에서 설정이 가능합니다.

로그인 페이지

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
    session_start();
    if(isset($_SESSION['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
    session_start();
    if(isset($_SESSION['user_id'])) {
        header("Location: login_successful.php");
        exit;
    }
?>

session_start() 함수로 사용자의 쿠키에서 phpsessid를 읽어온 뒤 파일을 찾아서 $_SESSION에 세션 값을 저장합니다.

그리고 if문과 isset을 이용해 user_id라는 이름의 세션값이 있는지 확인하고 있다면 프로필 페이지로 이동시킵니다.

없다면 로그인을 그대로 진행합니다.

 

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);

        // 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');
?>

 

수정 후

<?php
    session_start();
    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);
    
    if ($row = mysqli_fetch_array($sql_result)) {
        $nick = $row['nickname'];
        $update_sql = "update users set login=1 where nickname='$nick';";
        runSQL($update_sql);

        $_SESSION['user_id'] = $id;
        header("location:$url");
        exit;
    }
    
    header('Location: login2.php?result=failed');
?>

 

        $_SESSION['user_id'] = $id;

쿠키를 생성하던 부분을 세션에 값을 저장하는 코드로 변경하였습니다.


프로필페이지

login_successful.php

수정 전

<?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 
session_start();
$nickname = "";

if (isset($_SESSION["user_id"])) {
    require_once("mysql.php");
    $user_id = $_SESSION["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);
                // printf('<button class="link_tab logout-btn" onclick=\'logout("%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>

 

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

세션에 user_id 이름을 가진 값이 있는지 확인합니다.

 

    $user_id = $_SESSION["user_id"];

$user_id에 user_id세션의 값을 대입합니다.

 

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

세션이 없는 경우 로그인페이지로 이동시킵니다.


로그아웃

logout.php

수정 전

<?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");
?>

 

수정 후

<?php
session_start();
if (isset($_SESSION["user_id"])) {
    require_once("mysql.php");
    $user_id = $_SESSION["user_id"];
    $sql = "update users set login=0 where id='$user_id';";
    $result = runSQL($sql);
    session_unset();
    session_destroy();
    setcookie("PHPSESSID", "", time() - 60*60 ,"/");
}    
header("location: login2.php");
?>

 

    session_unset();
    session_destroy();

session_unset()은 현재 $_SESSION 배열에 입력된 세션 정보들을 초기화합니다.

session_destroy()는 세션 파일에 저장된 정보들을 삭제합니다.

세션은 php.ini에서 설정된 session.gc_maxlifetime인 세션의 유효시간이 지나도 삭제됩니다.
session.gc_maxlifetime가 30분인 경우 세션의 마지막 사용시간을 기점으로 30분이 지나면
가비지 컬렉터가 호출되어 세션파일을 삭제합니다.
ex) 은행 사이트에서 아무것도 안 하면 30분 뒤에 로그아웃

 

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

PHPSESSID 쿠키의 만료시간을 1시간 전으로 설정해서 브라우저에서 쿠키를 삭제합니다.


마무리

index.php

<?php
header("Location: login2.php");
?>

login2.php에서 세션이 있는지 확인을 거치니까 중복해서 하는 것 같아서 수정했습니다.