<현재 환경 세팅>
1. Virtual Box 7.1.4 + 우분투 리눅스 20.04
2. 우분투 APM (Apache2 + PHP + MySQL)
3. 기본 웹 루트 경로 /var/www/html
4. VScode SSH
5. 사진 등은 termius
충격적인 사실!!!!!!!!!!
phpsessid가 사용자의 로그인상태를 알려주는 척도가 아니란다.
너무 충격적이다..
이제껏 로그인한 후에 개발자도구를 이용해서 phpsessid가 생긴 거 보고 음~ 잘 로그인 되었군 허허 했는데
지금 확인해보니 login.php 페이지만 가도 phpsessid값이 발급된다...!!!!!!!!! 으악!!
phpsessid는 그냥 session_start(); 가 포함된 페이지에 접근한 사용자들에게 다 주는 거라고 한다..
일단 일련번호를 붙이는 느낌으로..
근데 이 세션 아이디를 발급받은 사용자가 로그인하면 말이 달라진다.
로그인 성공한 사용자의 세션아이디를 쿠키 헤더에 붙여서 다른 페이지를 요청하면 들어가지기 때문이다.
증거로 나는 방금 내 세션 아이디를 탈취했다.
세션아이디 탈취한 썰
어그로 끌어서 미안하다.
방금 내 사이트에서 로그인하고 콘솔 창에서 console.log(document.cookie);를 하니까
뙇 phpsessid가 나오길래 그거 긁어다가
버프스위트에서 요청헤더에 붙여넣고 index.php 파일을 리피터로 요청했는데
응답요청 렌더링 결과엔 login.php 파일이 아니라
index.php 페이지가 아아아주 잘 나왔다. (엄마..저 제 지갑에 있는 돈을 훔쳤어요..)
근데 응답데이터를 렌더링한 결과는 미친 개딱딱한 정적 페이지라서 이용할 수가 없었다.
사이트를 사용하기 위한 용도는 아닌 건가..?
아니면 또 뭔가 조치를 취해야 그 세션아이디로 사이트를 이용할 수 있나?
(intercept로 하면 됨)
위에서 말했듯이 phpsessid 자체는 session_start();가 포함된 페이지를 요청한 사용자들에게 붙이는
단순 구별자 같은 거고
이 세션아이디를 가진 사람들이 로그인을 했느냐 마느냐는
세션id를 키값으로 세션 데이터를 조회해야 알 수 있는데
로그인 성공 시 부여했던 $_SESSION['id']와 같은 값들이 해당 세션id와 연결된 사용자의 세션 데이터로 저장된다고 한다.
정리하자면 phpsessid는 그냥 session_start();가 포함된 페이지를 방문한 사용자들에게 모두 발급하는 세션 아이디이지만
만약 그 사용자가 로그인에 성공하면 이미 받은 세션 아이디를 key로 id등을 세션 변수에 저장한다.
세션 데이터: PHPSESSID / $_SESSION['id'] / 사이트 이용 중 받은 세션변수 등
↑
다른 페이지를 요청한 사용자의
세션id를 키값으로 세션 데이터를 찾아서
로그인 시 저장하는 세션변수( $_SESSION['id'] )가 발견되면
그 페이지에 재로그인할 것을 요구할 필요가 없다.
그니까 다른 페이지에 접근하기 전에 $_SESSION['id']에 값이 없으면 login.php로 돌려보내는 것이다.
역시... 이해했다고 생각했는데 해보면 또 다르다..
♨ 하고 싶은 거 + 해야 하는 거
1. 로그인 성공 시 사용자 아이디를 세션 변수에 넣고
그 세션 변수에 값이 있으면 다른 페이지 입장
없으면 로그인 페이지로 리다이렉션 + 오류문 출력
2. 로그아웃 버튼 구현
자바스크립트 이벤트 클릭 -> 로그아웃.php로 이동
근데 이걸 js 파일이랑 php파일로 나눠서 함수로 처리하는 버전
3. 로그아웃 시 phpsessid 재발급 설정
4. 세션 유효시간 설정
세션 쿠키 만료시간 설정
근데 이걸 다른 파일에 만들어서 include나 require로 처리
5. DB연동 코드 require/include로 처리
1) 세션 변수로 로그인 유지하기
로그인할 때 로그인 성공 시 이거 넣고 리다이렉션. (login_proc.php에서 처리)
회원가입할 때도 가입 완료후 바로 index로 갈 거면 이거 추가
$_SESSION['id'] = $id;
index.php 페이지에 session_start(); 쓰고 받은 세션변수 값 없으면 alert 출력하고 페이지 읽지 마
-> alert 창의 확인버튼 누르면 login.php로 리다이렉션
세션변수 값 있으면 index.php의 html코드 진행
<?php
session_start();
if(!isset($_SESSION['id'])) {
echo "<script>
alert('로그인이 필요한 서비스입니다.);
window.location.href = 'login.php';
</script>";
exit;
} ?> //이후 index.php의 html코드
이걸 필요한 페이지마다 추가 (게시물 업로드 페이지, 마이페이지 등등)
2) 로그아웃
㉮ index.php (등 로그아웃 버튼이 있는 모든 페이지에 아래 코드 필요)
<head>
<script src="logout_func.js"></script>
</head>
<body>
<button id="logout" onclick="logout()">로그아웃</button>
</body>
㉯ logout_func.js (버튼 요소의 클릭 이벤트와 php 파일을 잇는 다리 느낌)
function logout() {
var http = new XMLHttpRequest(); //요청을 변수에 저장
http.open('GET','logout.php',true); //get방식으로 저 파일요청. 근데 비동기식으로
http.onload = function() { //서버가 요청에 응답하면 함수 실행
if(http.status === 200) { //응답 상태가 200(요청 성공)이면
window.location.href = 'login.php'; //여기로 돌려
exit;
}
}
http.send(); //http.open요청 보냄.get요청은 url에 인자 있어서 () 상태로 보낸댜
}
//이런 걸 Ajax 요청이라 한다지..?
//새로고침 없이 비동기적으로 처리. 뭔가 안 기다리고 직접 요청하는 느낌
**비동기적 처리 : 다른 자바스크립트 코드 처리될 때까지 기다리지 않고 별동대 꾸려가지고 적진을 돌파하ㄴ..
**onload : 요청이 완전히 완료되었을 때만 실행
실제로는 open(요청 준비) -> send(요청 보냄) -> onload(응답 받고 함수 실행) 순으로 진행되는 건데
send는 오래 걸리기도 하고 응답 받으면 뭐 할 건지를 먼저 정해두는 게 비동기적(?)으로나 가독성 면에서 선호되는가봄
ajax에서는 응답 받았을 때 실행할 로직을 요청 보내기 전에 미리 준비하는 게 직관적이라고 평가되는 듯!
㉰ logout.php
<?php
session_start();
session_unset();
session_regenerate_id();
if(ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(),'',time() - 42000,$params['path'],$params['domain'],$params['secure'],$params['httponly']);
}
session_destroy();
header("location: login.php");
exit;
?>
세션 값 받으려고 일단 session_start();
세션 변수들 다 삭제
기존에 이 사용자가 쓰던 세션 아이디 삭제하고 새로운 세션 아이디 생성
쿠키 삭제 코드 : 세션이 쿠키를 사용 중이면 세션 쿠키 파라미터를 받아서 쿠키값을 설정함.
세션 이름(나는 phpsessid), 쿠키에 들어가는 값, 시간 만료시키기, 등등 파라미터들
세션 완전 종료. 서버에 남은 세션 데이터 모두 삭제(물론 로그아웃 한 사용자에 해당하는 데이터임)
다 완료하고 로그인 페이지로 이동
3) 세션ID 재발급
2번에서 함
session_regenerate_id(true);
true값이 있어야 이전에 쓰던 세션 아이디가 삭제된다고 함.
true 안 쓰면 이전에 쓰던 세션 아이디를 재활용하고.
phpsessid 값 자체가 로그인 정보를 가지지 않는다면 왜 굳이 재발급할 필요가 있을까 궁금했는데
세션 고정 공격이라는 게 또 있다 함.
세션 값 일단 탈취해서 다른 사람한테 그 세션 아이디 주고
그 사람이 그 세션 아이디를 가진 채로 로그인하길 기다리는 그런 공격인 듯
세션 아이디 재발급은 그런 공격을 예방하기에 좋다고 함.
4) 세션, 쿠키 유효 시간
㉮ 세션 유효 시간 설정
ini_set('session.gc_maxlifetime', 3600); // 서버에서 세션 데이터가 유지되는 시간 (초 단위)
session_start(); // 1시간 유지
㉯ 세션 쿠키 만료 시간 설정
session_start([
'cookie_lifetime' => 3600 // 쿠키가 유지되는 시간 (초 단위, 예: 1시간 = 3600초)
]); // 1시간 유지
난 한 세시간 해둘까. 그럼 10800을 3600대신 써 넣으면 된다.
이것도 마찬가지로 파일로 따로 분리해서 require나 include로 포함시키는 방법도 있다.
5) DB 연동 코드 따로 빼기
㉮ db_connection.php
<?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);
?>
㉯ db 필요한 파일 (로그인, 회원가입 관련 페이지 중 연동한 파일)에 추가
<?php
require 'db_connection.php';
?>
그래서 게시판 언제 만듦..?
'자습' 카테고리의 다른 글
웹 개발: 마이페이지 (2) | 2024.11.25 |
---|---|
CTF: 어드민은 내 것이다. (0) | 2024.11.23 |
웹 개발: 게시판 - 글 작성 (2) | 2024.11.13 |