[PHP] 세션 (Session)

Seo Joonsoo·2022년 6월 19일
0

php

목록 보기
8/23

Tistory로 작성된 글을 Velog로 옮기는 중입니다.
원글 : https://paric.tistory.com/781?category=805373

<?php
// page2.php

session_start();

echo 'Welcome to page #2<br />';

echo $_SESSION['favcolor']; // green
echo $_SESSION['animal'];   // cat
echo date('Y m d H:i:s', $_SESSION['time']);

// You may want to use SID here, like we did in page1.php
echo '<br /><a href="page1.php">page 1</a>';
?>

session_save_path (?string $path = null): string|false

현재 세션 저장 경로 가져오거나 설정합니다.

올바르게 수행하기 위해서는 session_start() 전에 session_save_path()를 호출해야 합니다.


session_start (array $options = []): bool

GET 또는 POST 요청을 통해 전달되거나 쿠키를 통해 전달된 세션 식별자를 기반으로 세션을 생성하거나 현재 세션을 재개합니다.

session_start() 가 호출되거나 세션이 자동으로 시작되면 PHP는 열기 및 읽기 세션 저장 핸들러를 호출합니다.

명명된 세션을 사용하려면 session_start() 를 호출하기 전에 session_name()을 사용하면 됩니다.

일반적으로 $options를 줄 일은 많지 않습니다.

예) 쿠키 수명 무시

session_start([
    'cookie_lifetime' => 86400,	// 쿠키수명 무시
]);

글로벌 변수 $_SESSION으로 접근해 값을 설정하거나 불러올 수 있습니다.

$_SESSION['userID'] = 'amdin';	// 세션 값 set
echo $_SESSION['userID'];	// 세션 값 get
/* result to:
admin
*/

session_id(?string $id = null): string|false

현재 세션의 세션 ID를 가져오거나 설정하는 데 사용됩니다.
session_id() 는 session_start() 보다 먼저 호출되어야 합니다.
흔히 SID라 하는 것은 Session ID를 의미합니다.

※ 세션 핸들러에 따라 세션 ID 내에서 모든 문자가 허용되는 것은 아닙니다.


session_name(?string $name = null): string|false

현재 세션의 이름을 가져오거나 설정하는 함수입니다.
$name 이주어진 경우 session_name() 은 세션 이름을 업데이트하고 이전 세션 이름 을 반환합니다.
새 세션 name이 제공되면 session_name() 은 HTTP 쿠키를 수정합니다.(session.transid 활성화된 경우 출력 내용)
HTTP 쿠키가 전송되면 session_name() 에서 오류가 발생합니다.
세션이 제대로 작동하려면 session_name()이 session_start()보다 먼저 호출되어야 합니다.

※ 세션 이름은 숫자로만 구성될 수 없으며 하나 이상의 문자가 있어야 합니다. 그렇지 않으면 매번 새로운 세션 ID가 생성됩니다.

session_gc(): int|false

쿠키와 마찮가지로 세션은 유효기간이 있습니다. 이는 php.ini에서 설정이 가능합니다.

세션 데이터 GC(가비지 컬렉션)를 수행하는 데 사용됩니다. PHP는 기본적으로 확률 기반 세션 GC를 수행합니다.

확률 기반 GC는 어느 정도 작동하지만 몇 가지 문제가 있습니다.

  1. 트래픽이 적은 사이트의 세션 데이터는 원하는 기간 내에 삭제되지 않을 수 있습니다.
  2. 트래픽이 많은 사이트의 GC는 너무 빈번한 GC일 수 있습니다.
  3. GC는 사용자의 요청에 따라 수행되며 사용자는 GC 지연을 경험하게 됩니다.

따라서 UNIX 계열 시스템의 경우 "cron"을 사용하는 프로덕션 시스템의 경우 주기적으로 GC를 실행하는 것이 좋습니다. session.gc_probability를 0 으로 설정하여 확률 기반 GC를 비활성화해야 합니다 .

<?php
// Need active session to initialize session data storage access.
session_start();

// Executes GC immediately
session_gc();

// Clean up session ID created by session_gc()
session_destroy();
?>

쿠키에대한 lifetime(수명)을 설정할 때 가장 많이 사용된다.

unset($_SESSION['userID']);

session_unset();

세션에 부여된 모든 값이 다 날아가게 된다.

session_destroy(): bool

현재 세션과 관련된 모든 데이터를 파괴합니다. 세션과 연결된 전역 변수를 설정 해제하거나 세션 쿠키를 설정 해제하지 않습니다. 세션 변수를 다시 사용하려면 session_start() 를 호출해야 합니다.

세션을 모두 종료하려면 세션 ID도 설정 해제해야 합니다. 쿠키를 사용하여 세션 ID를 전파하는 경우(기본 동작) 세션 쿠키를 삭제해야 합니다. (이를 위해 setcookie() 를 사용할 수 있습니다.)

일반 코드에서 session_destroy() 를 호출할 필요가 없습니다 . 세션 데이터를 파괴하는 대신 $_SESSION 배열을 정리하는 것이 좋습니다. 즉각적인 세션 삭제는 원치 않는 결과를 초래할 수 있습니다. 특히, 동시 요청이 있는 경우 다른 연결에서 갑작스러운 세션 데이터 손실이 발생할 수 있습니다.

session_status(): int

현재 세션 상태를 반환하는 데 사용됩니다.

[반환값]

  • PHP_SESSION_DISABLED 세션이 비활성화된 경우.
  • PHP_SESSION_NONE 세션이 활성화되었지만 아무 것도 존재하지 않는 경우.
  • PHP_SESSION_ACTIVE 세션이 활성화되고 하나가 존재하는 경우.
<?php
/**
* @return bool
*/
function is_session_started()
{
    if ( php_sapi_name() !== 'cli' ) {
        if ( version_compare(phpversion(), '5.4.0', '>=') ) {
            return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
        } else {
            return session_id() === '' ? FALSE : TRUE;
        }
    }
    return FALSE;
}

// Example
if ( is_session_started() === FALSE ) session_start();
?>

session_commit (): bool

현재 세션을 종료하고 세션 데이터를 저장합니다.

=> session_commit()은 session_write_close()의 별칭입니다.

일반적으로 세션 데이터는 session_write_close()를 호출할 필요 없이 스크립트가 종료된 후 저장 되지만 동시 쓰기를 방지하기 위해 세션 데이터가 잠겨 있으므로 한 번에 하나의 스크립트만 세션에서 작동할 수 있습니다. 세션과 함께 프레임 세트를 사용할 때 이 잠금으로 인해 프레임이 하나씩 로드되는 것을 경험하게 됩니다. 세션 변수에 대한 모든 변경이 완료되는 즉시 세션을 종료하여 모든 프레임을 로드하는 데 필요한 시간을 줄일 수 있습니다.

session_regenerate_id(bool $delete_old_session = false): bool

현재 세션 ID를 새 ID로 바꾸고 현재 세션 정보를 유지합니다.

세션이 공격자에게 노출될 경우 세션하이재킹 등 다양한 위험에 처할 수 있습니다. 이를 방지하기 위해 일정시간 또는 사용자의 행동(action)마다 새로운 세션을 부여하는 웹서비스들도 존재합니다.

현재 session_regenerate_id는 불안정한 네트워크(예: 모바일 및 WiFi 네트워크)를 잘 처리하지 못합니다. 따라서 session_regenerate_id를 호출하여 세션이 손실될 수 있습니다.

이전 세션 데이터를 즉시 폐기해서는 안 되며 폐기 타임스탬프를 사용하고 이전 세션 ID에 대한 액세스를 제어해야 합니다. 그렇지 않으면 페이지에 대한 동시 액세스로 인해 일관성 없는 상태가 발생하거나 세션이 손실될 수 있으며 클라이언트(브라우저) 측 경쟁 조건이 발생하고 불필요하게 많은 세션 ID가 생성될 수 있습니다.


즉각적인 세션 데이터 삭제는 세션 하이재킹 공격 탐지 및 방지도 비활성화합니다.

예제 #1

본 예제는 완전한 코드가 아닌 예시 입니다!

<?php
// 본 예제는 완전한 코드가 아닌 예시 입니다!
function my_session_start() {
    session_start();
    if (isset($_SESSION['destroyed'])) {
       if ($_SESSION['destroyed'] < time()-300) {
           // 이 사용자 세션의 모든 인증 상태를 제거합니다.
           // // 일반적으로 발생하지 않아야 합니다. 해킹 공격 또는 불안정한 네트워크로 인한 것일 수 있습니다.
           remove_all_authentication_flag_from_active_sessions($_SESSION['userid']);
           throw(new DestroyedSessionAccessException);
       }
       if (isset($_SESSION['new_session_id'])) {
           // 아직 완전히 만료되지 않았습니다. 불안정한 네트워크로 인해 쿠키가 손실될 수 있습니다..
           // 적절한 세션 ID 쿠키를 설정하기 위해 다시 시도합니다.
           // 참고: 제거하려는 경우 세션 ID를 다시 설정하지 마십시오.
           // 인증 플래그.
           session_commit();
           session_id($_SESSION['new_session_id']);
           // 새 세션 ID가 있어야 합니다.
           session_start();
           return;
       }
   }
}

function my_session_regenerate_id() {
    // 적절한 세션 ID를 설정하려면 새 세션 ID가 필요합니다.
    // 불안정한 네트워크로 인해 세션 ID가 설정되지 않은 경우.
    $new_session_id = session_create_id();
    $_SESSION['new_session_id'] = $new_session_id;
    
    // 제거를 위한 destroyed 타임스탬프 설정
    $_SESSION['destroyed'] = time();
    
    // 현재 세션을 쓰고 닫습니다.
    session_commit();

    // 새 세션 ID로 세션 시작
    session_id($new_session_id);
    ini_set('session.use_strict_mode', 0);
    session_start();
    ini_set('session.use_strict_mode', 1);
    
    // 새 세션에는 필요하지 않기 때문에 삭제하여 줍니다.
    unset($_SESSION['destroyed']);
    unset($_SESSION['new_session_id']);
}
?>
  • session_id() - 현재 세션 ID 가져오기 및/또는 설정
  • session_create_id() - 새 세션 ID 생성
  • session_start() - 새 세션 시작 또는 기존 세션 재개
  • session_destroy() - 세션에 등록된 모든 데이터를 삭제합니다.
  • session_reset() - 원래 값으로 세션 배열 다시 초기화
  • session_name() - 현재 세션 이름 가져오기 및/또는 설정
profile
여러분들 삶에 한 획을 더하고 싶습니다.

0개의 댓글