본문 바로가기

세션

업데이트됨

번역일: 2026년 7월 22일

이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.

원문 수정
2026년 7월 22일
번역 갱신
2026년 7월 22일

세션

소개

HTTP는 기본적으로 상태를 저장하지 않는(stateless) 프로토콜입니다. 세션은 이 한계를 보완하여 여러 요청에 걸쳐 사용자 정보를 유지할 수 있는 방법을 제공합니다. 세션 데이터는 이후 요청에서도 접근할 수 있도록 영속적인 저장소(백엔드)에 보관됩니다.

Laravel은 표현력 있고 일관된 API를 통해 다양한 세션 백엔드를 지원합니다. Memcached, Redis, 데이터베이스 등 널리 사용되는 저장소가 기본으로 포함되어 있습니다.

설정

세션 설정 파일은 config/session.php에 위치합니다. 이 파일에서 사용할 수 있는 옵션들을 꼭 확인해 두세요. Laravel의 기본 세션 드라이버는 database입니다.

driver 설정 옵션은 각 요청에서 세션 데이터를 어디에 저장할지를 결정합니다. Laravel이 기본으로 제공하는 드라이버는 다음과 같습니다.

  • file - storage/framework/sessions 디렉터리에 세션을 파일로 저장합니다.
  • cookie - 암호화된 쿠키에 세션을 저장합니다.
  • database - 관계형 데이터베이스에 세션을 저장합니다.
  • memcached / redis - 빠른 캐시 기반 저장소에 세션을 저장합니다.
  • dynamodb - AWS DynamoDB에 세션을 저장합니다.
  • array - PHP 배열에 세션을 저장하며, 데이터가 영속되지 않습니다.

NOTE

array 드라이버는 주로 테스트 환경에서 사용되며, 세션 데이터가 실제로 저장되지 않습니다.

드라이버 사전 준비

Database

database 세션 드라이버를 사용하려면 세션 데이터를 저장할 데이터베이스 테이블이 필요합니다. 일반적으로 Laravel 기본 마이그레이션 파일인 0001_01_01_000000_create_users_table.php에 이미 포함되어 있습니다. 만약 sessions 테이블이 없다면, 아래 Artisan 명령어로 마이그레이션 파일을 생성할 수 있습니다.

php artisan make:session-tablephp artisan migrate

Redis

Laravel에서 Redis 세션을 사용하려면 PECL을 통해 PhpRedis PHP 확장을 설치하거나, Composer로 predis/predis 패키지를 설치해야 합니다. Redis 설정에 대한 자세한 내용은 Redis 문서를 참고하세요.

NOTE

세션 저장에 사용할 Redis 연결은 SESSION_CONNECTION 환경 변수 또는 session.php 설정 파일의 connection 옵션으로 지정할 수 있습니다.

세션 데이터 다루기

데이터 조회

Laravel에서 세션 데이터를 다루는 방법은 크게 두 가지입니다. 하나는 전역 session 헬퍼를 사용하는 것이고, 다른 하나는 Request 인스턴스를 통해 접근하는 것입니다. 먼저 Request 인스턴스를 사용하는 방법을 살펴보겠습니다. Request는 라우트 클로저나 컨트롤러 메서드에 타입 힌팅으로 주입받을 수 있으며, Laravel 서비스 컨테이너가 자동으로 의존성을 주입해 줍니다.

<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\View\View; class UserController extends Controller { /** * 특정 사용자의 프로필을 표시합니다. */ public function show(Request $request, string $id): View { $value = $request->session()->get('key'); // ... $user = $this->users->find($id); return view('user.profile', ['user' => $user]); } }

세션에서 값을 가져올 때, get 메서드의 두 번째 인수로 기본값을 지정할 수 있습니다. 해당 키가 세션에 없을 경우 기본값이 반환됩니다. 기본값으로 클로저를 전달하면, 키가 없을 때 클로저가 실행되어 그 결과가 반환됩니다.

$value = $request->session()->get('key', 'default'); $value = $request->session()->get('key', function () { return 'default'; });

전역 Session 헬퍼

전역 session 함수를 사용해도 세션 데이터를 조회하고 저장할 수 있습니다. 문자열 인수 하나를 전달하면 해당 키의 값을 반환하고, 키-값 배열을 전달하면 세션에 데이터를 저장합니다.

Route::get('/home', function () { // 세션에서 데이터 조회 $value = session('key'); // 기본값 지정 $value = session('key', 'default'); // 세션에 데이터 저장 session(['key' => 'value']); });

NOTE

Request 인스턴스를 통한 세션 접근과 전역 session 헬퍼 사용 사이에는 실질적인 기능 차이가 없습니다. 두 방식 모두 테스트 케이스에서 제공되는 assertSessionHas 메서드를 통해 테스트할 수 있습니다.

전체 세션 데이터 조회

세션에 저장된 모든 데이터를 가져오려면 all 메서드를 사용합니다.

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

일부 세션 데이터 조회

onlyexcept 메서드를 사용하면 세션 데이터의 일부만 선택적으로 가져올 수 있습니다.

$data = $request->session()->only(['username', 'email']); $data = $request->session()->except(['username', 'email']);

세션 키 존재 여부 확인

has 메서드는 해당 키가 세션에 존재하고 값이 null이 아닐 때 true를 반환합니다.

if ($request->session()->has('users')) { // ... }

값이 null이더라도 키 자체가 세션에 존재하는지 확인하려면 exists 메서드를 사용합니다.

if ($request->session()->exists('users')) { // ... }

반대로, 해당 키가 세션에 없을 때를 확인하려면 missing 메서드를 사용합니다. 키가 없으면 true를 반환합니다.

if ($request->session()->missing('users')) { // ... }

데이터 저장

세션에 데이터를 저장할 때는 Request 인스턴스의 put 메서드나 전역 session 헬퍼를 사용합니다.

// Request 인스턴스를 통해 저장 $request->session()->put('key', 'value'); // 전역 session 헬퍼를 통해 저장 session(['key' => 'value']);

배열 세션 값에 항목 추가

push 메서드를 사용하면 배열로 저장된 세션 값에 새 항목을 추가할 수 있습니다. 예를 들어, user.teams 키에 팀 이름 배열이 저장되어 있다면 다음과 같이 새 값을 추가할 수 있습니다.

$request->session()->push('user.teams', 'developers');

값 조회 후 삭제

pull 메서드는 세션에서 값을 가져오는 동시에 해당 항목을 삭제합니다.

$value = $request->session()->pull('key', 'default');

세션 값 증감

세션에 정수 값이 저장되어 있다면, incrementdecrement 메서드로 값을 증가시키거나 감소시킬 수 있습니다.

$request->session()->increment('count'); $request->session()->increment('count', $incrementBy = 2); $request->session()->decrement('count'); $request->session()->decrement('count', $decrementBy = 2);

플래시 데이터

다음 요청에서만 잠시 사용할 데이터를 세션에 저장하고 싶을 때는 flash 메서드를 사용합니다. 플래시 데이터는 현재 요청과 바로 다음 HTTP 요청에서만 유효하며, 그 이후에는 자동으로 삭제됩니다. 주로 처리 결과 메시지나 일회성 알림을 표시할 때 유용합니다.

$request->session()->flash('status', '작업이 성공적으로 완료되었습니다!');

플래시 데이터를 여러 요청에 걸쳐 유지해야 한다면 reflash 메서드로 전체 플래시 데이터를 한 번 더 유지하거나, keep 메서드로 특정 데이터만 유지할 수 있습니다.

$request->session()->reflash(); $request->session()->keep(['username', 'email']);

현재 요청에서만 플래시 데이터를 즉시 사용하려면 now 메서드를 사용합니다.

$request->session()->now('status', '작업이 성공적으로 완료되었습니다!');

데이터 삭제

forget 메서드로 특정 세션 데이터를 삭제하거나, flush 메서드로 세션의 모든 데이터를 한 번에 삭제할 수 있습니다.

// 단일 키 삭제 $request->session()->forget('name'); // 여러 키 삭제 $request->session()->forget(['name', 'status']); // 세션 전체 비우기 $request->session()->flush();

세션 ID 재생성

세션 ID를 재생성하는 것은 세션 고정 공격(Session Fixation)을 방지하기 위한 중요한 보안 조치입니다.

Laravel의 스타터 킷이나 Laravel Fortify를 사용하는 경우 인증 과정에서 세션 ID가 자동으로 재생성됩니다. 직접 세션 ID를 재생성해야 한다면 regenerate 메서드를 사용하세요.

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

세션 ID를 재생성하면서 동시에 세션의 모든 데이터를 삭제하려면 invalidate 메서드를 사용합니다.

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

세션 캐시

Laravel의 세션 캐시는 개별 사용자 세션 범위 내에서 데이터를 캐시할 수 있는 편리한 기능입니다. 애플리케이션 전역 캐시와 달리, 세션 캐시는 세션별로 자동 격리되며 세션이 만료되거나 삭제될 때 함께 정리됩니다. get, put, remember, forgetLaravel 캐시에서 익숙하게 사용하던 메서드를 그대로 사용할 수 있되, 현재 세션 범위로 한정됩니다.

세션 캐시는 여러 요청에 걸쳐 유지하고 싶지만 영구 저장이 필요하지 않은 임시 사용자 데이터에 적합합니다. 폼 데이터, 임시 계산 결과, API 응답, 특정 사용자의 세션에 묶인 일시적 데이터 등이 좋은 예입니다.

세션 캐시는 세션의 cache 메서드를 통해 접근합니다.

$discount = $request->session()->cache()->get('discount'); $request->session()->cache()->put( 'discount', 10, now()->plus(minutes: 5) );

캐시 메서드에 대한 자세한 내용은 캐시 문서를 참고하세요.

세션 블로킹

WARNING

세션 블로킹을 사용하려면 원자적 잠금(atomic locks)을 지원하는 캐시 드라이버가 필요합니다. 현재 지원되는 드라이버는 memcached, dynamodb, redis, mongodb(공식 mongodb/laravel-mongodb 패키지 포함), database, file, array입니다. 단, cookie 세션 드라이버는 사용할 수 없습니다.

기본적으로 Laravel은 동일한 세션을 사용하는 요청들이 동시에 실행되는 것을 허용합니다. 예를 들어 JavaScript HTTP 라이브러리로 두 개의 요청을 동시에 보내면 두 요청 모두 동시에 처리됩니다. 대부분의 애플리케이션에서는 문제가 없지만, 서로 다른 엔드포인트에 동시에 세션 데이터를 쓰는 경우 세션 데이터가 유실될 수 있습니다.

이를 방지하기 위해 Laravel은 특정 세션에 대한 동시 요청을 제한하는 기능을 제공합니다. 라우트 정의에 block 메서드를 체이닝하면 됩니다. 아래 예시에서 /profile 엔드포인트로 들어온 요청은 세션 잠금을 획득합니다. 잠금이 유지되는 동안, 동일한 세션 ID를 가진 /profile 또는 /order 엔드포인트 요청은 앞선 요청이 완료될 때까지 대기합니다.

Route::post('/profile', function () { // ... })->block($lockSeconds = 10, $waitSeconds = 10); Route::post('/order', function () { // ... })->block($lockSeconds = 10, $waitSeconds = 10);

block 메서드는 두 개의 선택적 인수를 받습니다. 첫 번째 인수는 세션 잠금이 유지될 최대 초(seconds)이며, 요청이 그 전에 완료되면 잠금이 먼저 해제됩니다. 두 번째 인수는 잠금 획득을 대기할 최대 초입니다. 지정된 시간 내에 잠금을 획득하지 못하면 Illuminate\Contracts\Cache\LockTimeoutException이 발생합니다.

인수를 전달하지 않으면 잠금은 최대 10초 동안 유지되며, 요청은 최대 10초까지 잠금 획득을 대기합니다.

Route::post('/profile', function () { // ... })->block();

커스텀 세션 드라이버 추가

드라이버 구현

기존 세션 드라이버 중 적합한 것이 없다면, 직접 세션 핸들러를 작성할 수 있습니다. 커스텀 세션 드라이버는 PHP 내장 인터페이스인 SessionHandlerInterface를 구현해야 합니다. 이 인터페이스는 몇 가지 간단한 메서드로 구성됩니다. MongoDB를 예시로 한 기본 구현 구조는 다음과 같습니다.

<?php namespace App\Extensions; class MongoSessionHandler implements \SessionHandlerInterface { public function open($savePath, $sessionName) {} public function close() {} public function read($sessionId) {} public function write($sessionId, $data) {} public function destroy($sessionId) {} public function gc($lifetime) {} }

Laravel은 확장 클래스를 위한 별도의 기본 디렉터리를 제공하지 않으므로, 원하는 위치에 자유롭게 배치할 수 있습니다. 위 예시에서는 App\Extensions 디렉터리에 MongoSessionHandler를 배치했습니다.

각 메서드의 역할은 다음과 같습니다.

  • open: 주로 파일 기반 세션 저장소에서 사용합니다. Laravel에 file 드라이버가 이미 내장되어 있으므로, 대부분의 경우 이 메서드는 빈 채로 두어도 됩니다.
  • close: open과 마찬가지로 대부분의 드라이버에서 특별한 처리가 필요 없습니다.
  • read: 주어진 $sessionId에 해당하는 세션 데이터를 문자열로 반환해야 합니다. 직렬화(serialization)나 별도 인코딩은 필요하지 않습니다. Laravel이 자동으로 처리합니다.
  • write: 주어진 $sessionId와 연관된 $data 문자열을 MongoDB 등 영속 저장소에 저장해야 합니다. 직렬화는 Laravel이 이미 처리했으므로 별도로 수행하지 않아도 됩니다.
  • destroy: 주어진 $sessionId에 해당하는 세션 데이터를 영속 저장소에서 삭제해야 합니다.
  • gc: 주어진 $lifetime(UNIX 타임스탬프)보다 오래된 세션 데이터를 모두 삭제해야 합니다. Memcached나 Redis처럼 자체 만료 기능이 있는 저장소에서는 빈 채로 두어도 됩니다.

드라이버 등록

드라이버 구현이 완료되면 Laravel에 등록해야 합니다. Session 파사드extend 메서드를 사용하면 됩니다. extend서비스 프로바이더boot 메서드에서 호출해야 합니다. 기존 App\Providers\AppServiceProvider에 추가하거나, 별도의 서비스 프로바이더를 새로 만들어도 됩니다.

<?php namespace App\Providers; use App\Extensions\MongoSessionHandler; use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\Facades\Session; use Illuminate\Support\ServiceProvider; class SessionServiceProvider extends ServiceProvider { /** * 애플리케이션 서비스를 등록합니다. */ public function register(): void { // ... } /** * 애플리케이션 서비스를 부트스트랩합니다. */ public function boot(): void { Session::extend('mongo', function (Application $app) { // SessionHandlerInterface 구현체를 반환합니다. return new MongoSessionHandler; }); } }

드라이버 등록이 완료되면 SESSION_DRIVER 환경 변수 또는 config/session.php 설정 파일에서 mongo를 세션 드라이버로 지정하면 됩니다.

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 7월 22일