본문 바로가기

세션

업데이트됨

번역일: 2026년 10월 2일

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

원문 수정
2026년 10월 2일
번역 갱신
2026년 10월 2일

세션

소개

HTTP 기반 애플리케이션은 기본적으로 상태를 유지하지 않습니다(stateless). 세션은 이런 특성을 보완해, 여러 요청에 걸쳐 사용자에 대한 정보를 저장할 수 있게 해주는 수단입니다. 이렇게 저장된 사용자 정보는 보통 영속적인 저장소(백엔드)에 보관되며, 이후 요청에서도 다시 꺼내 쓸 수 있습니다.

라라벨은 직관적이고 통일된 API를 통해 다양한 세션 백엔드를 지원합니다. Memcached, Redis, 그리고 데이터베이스 같은 널리 쓰이는 백엔드를 기본으로 지원합니다.

설정

세션 설정 파일은 config/session.php에 있습니다. 이 파일에서 제공하는 옵션들을 꼭 한 번씩 살펴보시기 바랍니다. 라라벨은 기본적으로 database 세션 드라이버를 사용하도록 설정되어 있습니다.

driver 설정 옵션은 각 요청에서 세션 데이터를 어디에 저장할지를 결정합니다. 라라벨에는 다음과 같은 드라이버가 포함되어 있습니다.

  • file - storage/framework/sessions에 파일 형태로 저장됩니다.
  • cookie - 안전하게 암호화된 쿠키에 저장됩니다.
  • database - 관계형 데이터베이스에 저장됩니다.
  • memcached / redis - 빠른 속도의 캐시 기반 저장소 중 하나에 저장됩니다.
  • dynamodb - AWS DynamoDB에 저장됩니다.
  • array - PHP 배열에 저장되며, 영구적으로 유지되지 않습니다.

NOTE

array 드라이버는 주로 테스트 환경에서 사용되며, 세션에 저장한 데이터가 실제로 영속화되지 않도록 막아줍니다.

드라이버 사전 준비 사항

데이터베이스

database 세션 드라이버를 사용하려면 세션 데이터를 담을 테이블이 데이터베이스에 있어야 합니다. 보통 라라벨 기본 마이그레이션 파일인 0001_01_01_000000_create_users_table.php에 함께 포함되어 있습니다. 만약 어떤 이유로든 sessions 테이블이 없다면, make:session-table Artisan 명령어로 마이그레이션 파일을 생성할 수 있습니다.

php artisan make:session-tablephp artisan migrate

Redis

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

NOTE

SESSION_CONNECTION 환경 변수나 session.php 설정 파일의 connection 옵션을 통해 세션 저장에 사용할 Redis 연결을 지정할 수 있습니다.

세션과 상호작용하기

데이터 조회하기

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

<?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 헬퍼

전역 PHP 함수인 session을 사용해서도 세션 데이터를 조회하거나 저장할 수 있습니다. session 헬퍼를 문자열 인자 하나만 넘겨 호출하면 해당 세션 키의 값을 반환합니다. 반대로 키/값 쌍으로 이루어진 배열을 넘기면, 해당 값들을 세션에 저장합니다.

Route::get('/home', function () { // 세션에서 값 하나를 조회... $value = session('key'); // 기본값을 지정해서 조회... $value = session('key', 'default'); // 세션에 값 저장... session(['key' => 'value']); });

NOTE

HTTP 요청 인스턴스를 통해 세션을 다루는 방법과 전역 session 헬퍼를 사용하는 방법 사이에는 실질적인 차이가 거의 없습니다. 두 방식 모두 모든 테스트 케이스에서 사용 가능한 assertSessionHas 메서드로 테스트할 수 있습니다.

세션의 모든 데이터 조회하기

세션에 저장된 모든 데이터를 조회하려면 all 메서드를 사용하세요.

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

세션 데이터 일부만 조회하기

only와 except 메서드를 사용하면 세션 데이터 중 일부만 선택해서 가져올 수 있습니다.

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

세션에 항목이 존재하는지 확인하기

세션에 특정 항목이 존재하는지 확인하려면 has 메서드를 사용합니다. has 메서드는 항목이 존재하고 값이 null이 아닐 때 true를 반환합니다.

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

값이 null이더라도 항목 자체가 존재하는지 확인하려면 exists 메서드를 사용하세요.

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

세션에 항목이 존재하지 않는지 확인하려면 missing 메서드를 사용합니다. 항목이 없으면 true를 반환합니다.

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

데이터 저장하기

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

// 요청 인스턴스를 통한 저장... $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');

세션 값 증가/감소시키기

세션에 저장된 값이 정수이고 이를 증가시키거나 감소시키고 싶다면 increment와 decrement 메서드를 사용하면 됩니다.

$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', 'Task was successful!');

플래시 데이터를 여러 요청에 걸쳐 유지하고 싶다면 reflash 메서드를 사용하세요. 이 메서드는 모든 플래시 데이터를 한 번 더 유지시켜줍니다. 특정 데이터만 유지하고 싶다면 keep 메서드를 사용합니다.

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

현재 요청에서만 사용할 데이터를 저장하고 싶다면 now 메서드를 사용하세요.

$request->session()->now('status', 'Task was successful!');

데이터 삭제하기

forget 메서드를 사용하면 세션에서 특정 데이터를 제거할 수 있습니다. 세션의 모든 데이터를 제거하고 싶다면 flush 메서드를 사용하세요.

// 키 하나 삭제... $request->session()->forget('name'); // 키 여러 개 삭제... $request->session()->forget(['name', 'status']); $request->session()->flush();

세션 ID 재생성하기

세션 ID를 재생성하는 작업은 주로 악의적인 사용자가 세션 고정(session fixation) 공격을 시도하는 것을 막기 위해 수행합니다.

애플리케이션 스타터 키트나 Laravel Fortify를 사용하고 있다면, 라라벨이 인증 시점에 자동으로 세션 ID를 재생성해줍니다. 직접 세션 ID를 재생성해야 한다면 regenerate 메서드를 사용하세요.

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

세션 ID를 재생성하면서 동시에 세션의 모든 데이터를 제거하고 싶다면 invalidate 메서드를 사용하면 한 번에 처리할 수 있습니다.

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

세션 캐시

라라벨의 세션 캐시는 개별 사용자 세션에 한정된 데이터를 간편하게 캐싱할 수 있는 기능입니다. 애플리케이션 전역에서 공유되는 일반 캐시와 달리, 세션 캐시 데이터는 세션별로 자동으로 격리되며 세션이 만료되거나 파기될 때 함께 정리됩니다. 세션 캐시는 get, put, remember, forget 등 익숙한 라라벨 캐시 메서드를 그대로 지원하되, 그 범위가 현재 세션으로 한정된다는 점이 다릅니다.

세션 캐시는 같은 세션 내 여러 요청에 걸쳐 유지하고 싶지만 영구적으로 저장할 필요는 없는, 사용자별 임시 데이터를 다룰 때 특히 유용합니다. 예를 들어 폼 입력값, 임시 계산 결과, 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 세션 드라이버는 사용할 수 없습니다.

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

이를 방지하기 위해 라라벨은 같은 세션에 대한 동시 요청 수를 제한하는 기능을 제공합니다. 사용 방법은 간단합니다. 라우트 정의에 block 메서드를 체이닝하면 됩니다. 아래 예시에서는 /profile 엔드포인트로 들어오는 요청이 세션 락을 획득합니다. 이 락이 유지되는 동안, 같은 세션 ID를 공유하는 /profile이나 /order 엔드포인트로 들어오는 요청들은 먼저 들어온 요청이 끝날 때까지 대기한 후에 실행됩니다.

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

block 메서드는 두 개의 선택적 인자를 받습니다. 첫 번째 인자는 세션 락을 최대 몇 초 동안 유지할지를 지정합니다. 물론 이 시간이 지나기 전에 요청 처리가 끝나면 락은 그 즉시 해제됩니다.

두 번째 인자는 세션 락을 획득하기 위해 요청이 최대 몇 초까지 대기할지를 지정합니다. 지정한 시간 내에 락을 획득하지 못하면 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) {} }

라라벨에는 이런 확장 기능을 담아둘 기본 디렉터리가 따로 정해져 있지 않으므로, 원하는 위치에 자유롭게 배치하면 됩니다. 이 예시에서는 Extensions라는 디렉터리를 만들어 그 안에 MongoSessionHandler를 두었습니다.

각 메서드의 역할이 이름만으로는 바로 와닿지 않을 수 있으니, 각각이 어떤 역할을 하는지 살펴보겠습니다.

  • open 메서드는 주로 파일 기반 세션 저장 시스템에서 사용됩니다. 라라벨에는 이미 file 세션 드라이버가 포함되어 있으므로, 이 메서드에 특별한 내용을 작성할 일은 거의 없습니다. 비워둬도 무방합니다.
  • close 메서드 역시 open과 마찬가지로 대부분의 드라이버에서는 특별히 구현할 필요가 없습니다.
  • read 메서드는 주어진 $sessionId에 해당하는 세션 데이터를 문자열 형태로 반환해야 합니다. 세션 데이터를 조회하거나 저장할 때 직렬화나 별도의 인코딩 처리를 할 필요는 없습니다. 라라벨이 이 작업을 대신 처리해줍니다.
  • write 메서드는 $sessionId에 연결된 $data 문자열을 MongoDB와 같이 원하는 영속 저장소에 기록해야 합니다. 이번에도 직렬화는 직접 처리할 필요가 없습니다. 라라벨이 이미 처리를 끝낸 상태로 데이터를 넘겨줍니다.
  • destroy 메서드는 $sessionId와 연관된 데이터를 영속 저장소에서 제거해야 합니다.
  • gc 메서드는 초 단위로 주어지는 $lifetime보다 오래된 모든 세션 데이터를 삭제해야 합니다. Memcached나 Redis처럼 자체적으로 만료 기능을 갖춘 시스템이라면 이 메서드는 비워둬도 됩니다.

드라이버 등록하기

드라이버 구현을 마쳤다면, 이제 라라벨에 등록할 차례입니다. 라라벨 세션 백엔드에 드라이버를 추가로 등록하려면 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년 10월 2일