webman 세션 관리

예제

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function hello(Request $request)
    {
        $name = $request->get('name');
        $session = $request->session();
        $session->set('name', $name);
        return response('hello ' . $session->get('name'));
    }
}

$request->session();를 통해 Workerman\Protocols\Http\Session 인스턴스를 얻고, 인스턴스의 메서드를 사용하여 세션 데이터를 추가, 수정, 삭제할 수 있습니다.

주의: 세션 객체가 파괴될 때 자동으로 세션 데이터를 저장하므로, $request->session()이 반환하는 객체를 전역 배열이나 클래스 멤버에 저장하면 세션이 저장되지 않을 수 있습니다.

모든 세션 데이터 가져오기

$session = $request->session();
$all = $session->all();

반환하는 것은 배열입니다. 세션 데이터가 없으면 빈 배열을 반환합니다.

세션에서 특정 값 가져오기

$session = $request->session();
$name = $session->get('name');

데이터가 없으면 null을 반환합니다.

두 번째 인자로 기본 값을 전달할 수도 있습니다. 세션 배열에서 일치하는 값을 찾지 못하면 기본 값을 반환합니다. 예:

$session = $request->session();
$name = $session->get('name', 'tom');

세션 저장하기

특정 데이터를 저장할 때는 set 메서드를 사용합니다.

$session = $request->session();
$session->set('name', 'tom');

set은 반환 값이 없으며, 세션 객체가 파괴될 때 세션이 자동으로 저장됩니다.

여러 값을 저장할 때는 put 메서드를 사용합니다.

$session = $request->session();
$session->put(['name' => 'tom', 'age' => 12]);

마찬가지로 put도 반환 값이 없습니다.

세션 데이터 삭제하기

특정하거나 여러 세션 데이터를 삭제하려면 forget 메서드를 사용합니다.

$session = $request->session();
// 한 항목 삭제
$session->forget('name');
// 여러 항목 삭제
$session->forget(['name', 'age']);

또한 시스템에서는 delete 메서드를 제공하며, forget 메서드와의 차이는 delete는 한 항목만 삭제할 수 있습니다.

$session = $request->session();
// $session->forget('name');와 동등합니다.
$session->delete('name');

세션의 특정 값을 가져오고 삭제하기

$session = $request->session();
$name = $session->pull('name');

아래 코드와 동일한 효과입니다.

$session = $request->session();
$value = $session->get($name);
$session->delete($name);

해당 세션이 존재하지 않으면 null을 반환합니다.

모든 세션 데이터 삭제하기

$request->session()->flush();

반환 값이 없으며, 세션 객체가 파괴될 때 세션이 저장소에서 자동으로 삭제됩니다.

해당 세션 데이터 존재 여부 판단하기

$session = $request->session();
$has = $session->has('name');

위 코드에서 해당 세션이 존재하지 않거나 세션 값이 null인 경우 false를 반환하고, 그렇지 않으면 true를 반환합니다.

$session = $request->session();
$has = $session->exists('name');

위 코드도 세션 데이터 존재 여부를 판단하는 데 사용되며, 차이점은 해당 세션 항목의 값이 null일 때도 true를 반환합니다.

헬퍼 함수 session()

webman은 같은 기능을 수행하는 헬퍼 함수 session() 을 제공합니다.

// 세션 인스턴스 가져오기
$session = session();
// 동등합니다.
$session = $request->session();

// 특정 값 가져오기
$value = session('key', 'default');
// 다음과 동등합니다.
$value = session()->get('key', 'default');
// 다음과 동등합니다.
$value = $request->session()->get('key', 'default');

// 세션 값 설정하기
session(['key1'=>'value1', 'key2' => 'value2']);
// 다음과 동일합니다.
session()->put(['key1'=>'value1', 'key2' => 'value2']);
// 다음과 동일합니다.
$request->session()->put(['key1'=>'value1', 'key2' => 'value2']);

설정 파일

세션 설정 파일은 config/session.php에 위치하며, 내용은 다음과 유사합니다:

use Webman\Session\FileSessionHandler;
use Webman\Session\RedisSessionHandler;
use Webman\Session\RedisClusterSessionHandler;

return [
    // FileSessionHandler::class 또는 RedisSessionHandler::class 또는 RedisClusterSessionHandler::class 
    'handler' => FileSessionHandler::class,

    // handler가 FileSessionHandler::class일 경우 값은 file,
    // handler가 RedisSessionHandler::class일 경우 값은 redis
    // handler가 RedisClusterSessionHandler::class일 경우 값은 redis_cluster 즉, redis 클러스터
    'type'    => 'file',

    // 서로 다른 handler는 서로 다른 설정을 사용합니다.
    'config' => [
        // type이 file일 때의 설정
        'file' => [
            'save_path' => runtime_path() . '/sessions',
        ],
        // type이 redis일 때의 설정
        'redis' => [
            'host'      => '127.0.0.1',
            'port'      => 6379,
            'auth'      => '',
            'timeout'   => 2,
            'database'  => '',
            'prefix'    => 'redis_session_',
        ],
        'redis_cluster' => [
            'host'    => ['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7001'],
            'timeout' => 2,
            'auth'    => '',
            'prefix'  => 'redis_session_',
        ]

    ],

    'session_name' => 'PHPSID', // session_id를 저장하는 쿠키 이름
    'auto_update_timestamp' => false,  // 세션 자동 갱신 여부, 기본값은 꺼짐
    'lifetime' => 7*24*60*60,          // 세션 만료 시간
    'cookie_lifetime' => 365*24*60*60, // session_id를 저장하는 쿠키 만료 시간
    'cookie_path' => '/',              // session_id를 저장하는 쿠키 경로
    'domain' => '',                    // session_id를 저장하는 쿠키 도메인
    'http_only' => true,               // httpOnly 활성화 여부, 기본값은 활성화
    'secure' => false,                 // https에서만 세션 활성화 여부, 기본값은 꺼짐
    'same_site' => '',                 // CSRF 공격 방지 및 사용자 추적 방지를 위해, 선택 가능한 값: strict/lax/none
    'gc_probability' => [1, 1000],     // 세션 수거 확률
];

보안 관련

세션을 사용할 때 클래스의 인스턴스 객체를 직접 저장하는 것은 권장하지 않습니다. 특히 제어할 수 없는 클래스 인스턴스를 반직렬화할 경우 잠재적인 위험이 있을 수 있습니다.