PHP/PHP

[PHP] php 세션(Session) 사용하기

테서르 2021. 2. 22. 12:45
반응형

목차

  1. 세션 시작
  2. 세션 변수 사용
  3. 세션 변수 해제
  4. 세션 변수 등록 확인
  5. 세션 id 변경
  6. 세션 종료
  7. 추가 1. 세션 유지시간
  8. 추가 2. 추가 보안설정

 

세션(Session)은 모든 정보가 사용자 측의 컴퓨터에 저장되는 쿠키와는 달리 웹 서버에 정보를 저장하고 사용자 측에는 접근할 수 있는 키 값을 저장한다.

웹 서버에 데이터가 저장되고 필요할 때마다 브라우저에서 키 값으로 서버에 요청을 한다. 그리고 브라우저를 종료하는 시점에서 세션이 삭제가 되도록 설정이 가능해서 쿠키에만 데이터를 저장하는 것보다는 보안성이 높다.

 

사용하는 법도 쉽기 때문에 로그인과 같은 인증 처리에 많이 사용이 된다.

 

 

1. 세션 시작하기

<?php
//세션 시작
session_start();

php에서 세션을 사용하기 위해서는 session_start()를 사용하여 세션을 시작한다. 사용자 정보가 웹 서버에 없을 경우에는 새로운 세션을 생성하고, 이미 세션이 생성되어 있다면 기존 세션을 사용한다.

 

생성된 세션의 키 값은 브라우저의 개발자 도구를 통해 쉽게 확인할 수 있다.

생성된 세션의 이름과 접근을 할 수 있는 키 값

 

php에서 세션을 생성하면 기본적으로 세션의 이름은 PHPSESSID로 저장된다. php 설정파일인 php.ini에서 변경이 가능하다. 일시적인 변경이 필요하면 session_name('변경할 이름')을 사용하여 변경을 할 수 있다. session_name()을 사용하려면 session_start()보다 위에 입력을 해야 오류없이 작동한다.

 

session_start() 함수를 같은 파일에서 여러번 실행하게 된다면 이미 세션이 실행되었다는 알림을 출력하니 session_id() 함수를 사용하여 현재 생성된 세션이 있는지 확인한 후 세션을 시작하는 것이 좋다.

<?php
// 발급된 세션 id가 있다면 세션의 id를, 없다면 false 반환
if(!session_id()) {
// id가 없을 경우 세션 시작
    session_start();
}

 

2. 세션 변수 사용

<?php
//세션 시작
session_start();

//세션 변수 등록
$_SESSION['userName'] = 'tester';
$_SESSION['userPw'] = '1234';

//등록된 변수 사용
echo "userName 값: ".$_SESSION['userName']."<br/>";
echo "userPw 값: ".$_SESSION['userPw'];

세션을 사용하여 변수를 등록하려면 $_SESSION['변수명'] = Data 형태로 사용하면 된다. 위 코드처럼 $_SESSION['userName'] = 'tester'; 라고 하면 userName이라는 세션 변수에 tester라는 값을 저장한다는 의미다.

등록된 세션 변수를 사용하는 것도 등록과 같다. $_SESSION['변수명'] 형태로 사용한다. 그대로 쓰면 코드가 길어지니 php 변수에 저장하여 사용하는게 편하다.

 

세션 변수 사용

 

3. 세션 변수 해제

<?php
//세션 시작
session_start();
//세션 변수 등록
$_SESSION['userName'] = 'tester';

echo "userName 값: ".$_SESSION['userName'];

//등록된 변수 해제
unset($_SESSION['userName']);
echo "userName 값: ".$_SESSION['userName'];

등록된 변수의 해제는 unset()을 사용하면 된다. unset($_SESSION['변수명']) 형태로 입력하면 해당하는 변수가 등록이 해제되어 사용을 할 수 없게 된다.

 

unset으로 해제한 후 변수를 호출하면 정의되지 않음 에러가 발생한다.

만약 모든 변수의 등록을 해제하고 싶으면 session_unset() 함수를 사용하면 모든 변수의 등록이 해제된다. 세션을 완전히 종료하고 싶다면 session_destroy()를 사용하여 세션 파일과 브라우저의 쿠키를 삭제하여 세션이 종료된다.

 

4. 세션 변수 등록 확인

<?php
// 세션 시작
session_start();

//변수 등록
$_SESSION['userId'] = '';

//변수 등록 여부 확인
if(!isset($_SESSION['userId'])) {
    $_SESSION['userId'] = 'data1';
    echo '새로운 변수 생성';
} else {
    $_SESSION['userId'] = 'data2';
    echo '기존 변수 데이터 변경';
}
echo '<br/>'.$_SESSION['userId'];

isset() 함수를 사용하면 해당 변수가 등록이 되어있는지 확인을 할 수 있다. isset($_SESSION['변수명']) 형태로 사용하며 만약 해당 변수가 등록이 되어있다면 true값을 반환, 등록이 되지 않았다면 false를 반환한다.

 

위 코드는 변수가 생성되지 않았다면 data1을, 생성이 되어있다면 data2를 저장하고 변수의 값을 출력하는 코드다. 실행을 해 보면 변수가 등록이 되어 있으므로 data2가 출력이 되는 것을 볼 수 있다.

 

isset() 함수로 변수 여부 확인

 

 

5. 세션 id 변경

php의 세션은 브라우저의 쿠키에 등록된 id를 사용하여 서버에 저장된 데이터에 접근을 한다. 그래서 세션 id를 탈취당한다면 세션에 저장된 데이터들 또한 탈취 당할 위험이 높아진다.

 

그래서 일반적으로 사용자의 인증정보에 변동(로그인 및 로그아웃), 설정 변경 등 중요한 변경 사항이 있을때 세션 id를 변경한다. php에서는 session_regenerate_id() 함수를 사용하여 새로운 id를 발급받아 쿠키를 생성한다.

 

<?php
// 세션 시작
session_start();

// 현재 세션 id 확인
echo session_id();
echo '<br/><br/>';
// 세션 id 신규 발급
session_regenerate_id();

// 신규 발급된 id 확인
echo session_id();

 

세션 id 변경 확인

 

session_regenerate_id() 함수의 기본 설정은 세션 id를 변경 후 이전의 세션 데이터를 삭제하지 않는다. id만 새로 발급하여 데이터를 복제하는 방식이다. 그래서 서버에서 확인을 해 보면 id는 다르지만 같은 데이터를 가지고 있는 세션 파일이 확인이 된다.

이전 데이터를 지우고 싶다면 session_regenerate_id(true)형식으로 파라미터를 사용하여 이전 세션 데이터를 삭제하도록 해야 한다. 이렇게 하면 새로운 id가 발급되고 이전의 세션은 완전히 삭제된다.

 

 

6. 세션 종료하기

기본적으로 php의 세션을 브라우저가 연결을 끊고 일정 시간이 지나면 세션 데이터가 저장된 파일을 삭제하는 것으로 완전히 종료가 된다.

 

그러나 사용자의 요청으로 세션을 종료하는 것으로 로그아웃 기능을 만들 때는 직접 세션을 종료시켜야 한다. 그럴때는 session_destroy() 함수를 사용한다.

<?php
//세션 데이터에 접근하기 위해 세션 시작
if (!session_id()) {
  session_start();
}
// 세션 데이터 빈 배열로 초기화
$_SESSION = array();
// 또는 session_unset(); 사용

// 세션 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();

php 공식 문서에 따르면 session_destroy() 함수는 현재 세션의 모든 데이터를 파괴하는 함수다. 즉, 세션의 데이터가 저장되어 있는 파일을 삭제하는 것이다.

 

그러나 단지 세션 파일을 삭제하는 것이지 세션 ID 값이 있는 쿠키는 그대로 남아있게 된다. 그래서 setcookie()함수를 사용해 세션 ID가 저장된 쿠키를 강제로 만료시켜 삭제를 하는 것이다.

 

또한 $_SESSION 변수에 빈 배열을 넣는 이유도 같다. session_destroy() 함수가 $_SESSION 변수까지 해제하는 것이 아니기 때문에 빈 배열을 넣어 초기화 시켜주는 것이다. session_unset() 함수를 사용해도 같은 동작을 실행한다.

 

 

 

추가 1. 세션 유지시간

설정파일인 php.ini 파일을 보면 php의 기본 세션 유지 시간은 1440초로 설정이 되어 있다.

php 세션의 garbage collection 실행을 설정하는 항목

기본적으로 php의 세션의 관리는 확률로 이루어 진다. gc_probability / gc_divisor 의 확률로 gc_maxlifetime에서 지정한 시간이 지난 세션 데이터를 삭제한다.

예시 이미지에는 gc_probability가 0으로 설정되어 있지만, 주석을 보면 일반적으로 1로 설정이 되는 듯하다. 즉, 세션이 시작될 때 1/1000의 확률로 gc가 실행이 되고, 모든 세션을 조회하여 마지막 요청으로부터gc_maxlifetime에 설정된 시간이 지난 세션이 있다면 삭제를 한다.

 

그러니 단순하게 세션 유지 시간을 증가시키고 싶다면 session.gc_maxlifetime의 값을 올려주면 된다. 기본값은 1440초로 24분이다.

 

session.gc의 실행방식이 모든 세션의 생성시간을 조회하는것이다 보니 세션이 많이 생성되어 있을 경우 서버에 부담을 주게 된다. 그래서 php 공식 문서를 보면 UNIX 형태의 서버는 session.gc_probability의 값을 0으로 설정하고 예약 실행 스케쥴러인 cron을 사용하여 수동으로 실행하는 편이 좋다고 되어있다.

참조 링크: https://www.php.net/manual/en/function.session-gc.php

 

PHP: session_gc - Manual

 

www.php.net

 

 

추가 2. 추가 보안설정

세션이 단순 쿠키만 사용하는 것 보다는 데이터의 보안이 좋은것이지, 쿠키를 함께 사용하기 때문에 추가적인 설정을 해 주어야 한다. 일부 비활성화 되어 있는 설정들을 찾아 활성화로 바꾸어야 한다.

 

; 초기화 되지 않은 세션ID 생성 방지. URL로 세션ID 전달 방지
session.use_strict_mode = 1

; 쿠키만 사용하여 세션ID 저장. URL로 세션ID 전달 방지
session.use_only_cookies = 1

; 쿠키가 http 통신을 통해서만 전달되도록 설정. 자바스크립트에서 접근하는 것을 방지
session.cookie_httponly = 1

; https를 사용하는 경우 https만을 통해서 전달되도록 설정. 기본설정은 주석처리. 상황에 따라 설정
session.cookie_secure = 1

 

위의 설정으로 어느정도 보안이 되지만 추가적인 설정을 하고 싶다면 php 공식 문서에서 권장하는 세션 설정이 있으니 참조하여 설정하면 된다.

참조링크: https://www.php.net/manual/en/session.security.ini.php

 

PHP: Securing Session INI Settings - Manual

Warning: Calling `ini_set('session.use_only_cookies', 1)` returns FALSE if `session_start()` has already been called.

www.php.net

반응형