HTTP 요청
업데이트됨번역일: 2026년 10월 1일
이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.
- 원문 수정
- 2026년 11월 7일
- 번역 갱신
- 2026년 10월 1일
HTTP 요청
소개
라라벨의 Illuminate\Http\Request 클래스는 애플리케이션에서 현재 처리 중인 HTTP 요청과 객체지향적으로 상호작용할 수 있는 방법을 제공합니다. 이 클래스를 통해 요청과 함께 제출된 입력값, 쿠키, 파일을 간편하게 조회할 수 있습니다.
요청과 상호작용하기
요청 객체 접근하기
의존성 주입을 통해 현재 HTTP 요청 객체를 얻으려면, 라우트 클로저나 컨트롤러 메서드에 Illuminate\Http\Request 클래스를 타입힌트로 지정하면 됩니다. 라라벨의 서비스 컨테이너가 들어오는 요청 객체를 자동으로 주입해 줍니다.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 새로운 사용자를 저장합니다.
*/
public function store(Request $request): RedirectResponse
{
$name = $request->input('name');
// 사용자 저장 로직...
return redirect('/users');
}
}앞서 언급했듯이, 라우트 클로저에서도 Illuminate\Http\Request 클래스를 타입힌트로 지정할 수 있습니다. 서비스 컨테이너는 클로저가 실행될 때 들어오는 요청을 자동으로 주입합니다.
use Illuminate\Http\Request;
Route::get('/', function (Request $request) {
// ...
});의존성 주입과 라우트 매개변수
컨트롤러 메서드가 라우트 매개변수의 입력값도 함께 받아야 한다면, 다른 의존성 뒤에 라우트 매개변수를 나열하면 됩니다. 예를 들어 다음과 같이 라우트가 정의되어 있다면:
use App\Http\Controllers\UserController;
Route::put('/user/{id}', [UserController::class, 'update']);여전히 Illuminate\Http\Request를 타입힌트로 지정하면서 id 라우트 매개변수에 접근하려면, 다음과 같이 컨트롤러 메서드를 정의합니다.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 주어진 사용자를 업데이트합니다.
*/
public function update(Request $request, string $id): RedirectResponse
{
// 사용자 업데이트 로직...
return redirect('/users');
}
}요청 경로, 호스트, 메서드
Illuminate\Http\Request 인스턴스는 애플리케이션으로 들어온 HTTP 요청을 검사할 수 있는 다양한 메서드를 제공하며, Symfony\Component\HttpFoundation\Request 클래스를 확장하고 있습니다. 유용한 메서드 몇 가지를 아래에서 살펴보겠습니다.
요청 경로 조회하기
path 메서드는 요청의 경로 정보를 반환합니다. 예를 들어 들어오는 요청이 http://example.com/foo/bar를 대상으로 한다면, path 메서드는 foo/bar를 반환합니다.
$uri = $request->path();요청 경로 / 라우트 검사하기
is 메서드를 사용하면 들어온 요청 경로가 주어진 패턴과 일치하는지 확인할 수 있습니다. 이 메서드를 사용할 때 * 문자를 와일드카드로 사용할 수 있습니다.
if ($request->is('admin/*')) {
// ...
}routeIs 메서드를 사용하면 들어온 요청이 이름이 지정된 라우트와 일치하는지 확인할 수 있습니다.
if ($request->routeIs('admin.*')) {
// ...
}요청 URL 조회하기
들어온 요청의 전체 URL을 조회하려면 url 또는 fullUrl 메서드를 사용할 수 있습니다. url 메서드는 쿼리 문자열을 제외한 URL을 반환하고, fullUrl 메서드는 쿼리 문자열을 포함한 URL을 반환합니다.
$url = $request->url();
$urlWithQueryString = $request->fullUrl();현재 URL에 쿼리 문자열 데이터를 추가하고 싶다면 fullUrlWithQuery 메서드를 호출하면 됩니다. 이 메서드는 전달된 쿼리 문자열 변수 배열을 현재 쿼리 문자열과 병합합니다.
$request->fullUrlWithQuery(['type' => 'phone']);주어진 쿼리 문자열 매개변수 없이 현재 URL을 얻고 싶다면 fullUrlWithoutQuery 메서드를 사용할 수 있습니다.
$request->fullUrlWithoutQuery(['type']);요청 호스트 조회하기
들어온 요청의 "호스트"를 조회하려면 host, httpHost, schemeAndHttpHost 메서드를 사용할 수 있습니다.
$request->host();
$request->httpHost();
$request->schemeAndHttpHost();요청 메서드 조회하기
method 메서드는 요청에 사용된 HTTP 동사를 반환합니다. isMethod 메서드를 사용하면 HTTP 동사가 주어진 문자열과 일치하는지 확인할 수 있습니다.
$method = $request->method();
if ($request->isMethod('post')) {
// ...
}요청 헤더
header 메서드를 사용해 Illuminate\Http\Request 인스턴스에서 요청 헤더를 조회할 수 있습니다. 요청에 해당 헤더가 존재하지 않으면 null이 반환됩니다. 다만 header 메서드의 두 번째 인수로 기본값을 지정할 수도 있으며, 요청에 헤더가 없을 때 이 값이 반환됩니다.
$value = $request->header('X-Header-Name');
$value = $request->header('X-Header-Name', 'default');hasHeader 메서드를 사용하면 요청에 특정 헤더가 포함되어 있는지 확인할 수 있습니다.
if ($request->hasHeader('X-Header-Name')) {
// ...
}편의상 bearerToken 메서드를 사용해 Authorization 헤더에서 베어러 토큰을 조회할 수도 있습니다. 해당 헤더가 없다면 빈 문자열이 반환됩니다.
$token = $request->bearerToken();요청 IP 주소
ip 메서드를 사용하면 애플리케이션에 요청을 보낸 클라이언트의 IP 주소를 조회할 수 있습니다.
$ipAddress = $request->ip();프록시로 전달된 모든 클라이언트 IP 주소 배열을 조회하고 싶다면 ips 메서드를 사용할 수 있습니다. "원본" 클라이언트 IP 주소는 배열의 맨 끝에 위치합니다.
$ipAddresses = $request->ips();일반적으로 IP 주소는 신뢰할 수 없는, 사용자가 제어할 수 있는 입력으로 간주해야 하며 정보 제공 목적으로만 사용하는 것이 좋습니다.
콘텐츠 협상
라라벨은 들어온 요청의 Accept 헤더를 통해 요청된 콘텐츠 타입을 검사할 수 있는 여러 메서드를 제공합니다. 먼저 getAcceptableContentTypes 메서드는 요청이 허용하는 모든 콘텐츠 타입을 담은 배열을 반환합니다.
$contentTypes = $request->getAcceptableContentTypes();accepts 메서드는 콘텐츠 타입 배열을 받아, 요청이 그중 하나라도 허용한다면 true를 반환합니다. 그렇지 않으면 false를 반환합니다.
if ($request->accepts(['text/html', 'application/json'])) {
// ...
}prefers 메서드를 사용해 주어진 콘텐츠 타입 배열 중 요청이 가장 선호하는 콘텐츠 타입을 판단할 수도 있습니다. 주어진 콘텐츠 타입 중 어느 것도 요청에서 허용되지 않는다면 null이 반환됩니다.
$preferred = $request->prefers(['text/html', 'application/json']);많은 애플리케이션이 HTML 또는 JSON만 제공하므로, expectsJson 메서드를 사용하면 들어온 요청이 JSON 응답을 기대하는지 빠르게 판단할 수 있습니다.
if ($request->expectsJson()) {
// ...
}PSR-7 요청
PSR-7 표준은 요청과 응답을 포함한 HTTP 메시지에 대한 인터페이스를 규정합니다. PSR-7 요청 인스턴스를 라라벨 요청 대신 받고 싶다면 먼저 몇 가지 라이브러리를 설치해야 합니다. 라라벨은 Symfony HTTP Message Bridge 컴포넌트를 사용해 일반적인 라라벨 요청과 응답을 PSR-7 호환 구현체로 변환합니다.
composer require symfony/psr-http-message-bridgecomposer require nyholm/psr7이 라이브러리를 설치한 후에는 라우트 클로저나 컨트롤러 메서드에 요청 인터페이스를 타입힌트로 지정해 PSR-7 요청을 얻을 수 있습니다.
use Psr\Http\Message\ServerRequestInterface;
Route::get('/', function (ServerRequestInterface $request) {
// ...
});NOTE
라우트나 컨트롤러에서 PSR-7 응답 인스턴스를 반환하면, 프레임워크가 자동으로 이를 라라벨 응답 인스턴스로 변환하여 표시해 줍니다.
입력값
입력값 조회하기
모든 입력값 조회하기
들어온 요청의 모든 입력값을 array 형태로 조회하려면 all 메서드를 사용할 수 있습니다. 이 메서드는 요청이 HTML 폼으로 전송되었든 XHR 요청으로 전송되었든 상관없이 사용할 수 있습니다.
$input = $request->all();collect 메서드를 사용하면 들어온 요청의 모든 입력값을 컬렉션으로 조회할 수도 있습니다.
$input = $request->collect();collect 메서드는 요청 입력값의 일부분만 컬렉션으로 조회하는 것도 허용합니다.
$request->collect('users')->each(function (string $user) {
// ...
});특정 입력값 조회하기
몇 가지 간단한 메서드만 사용하면, HTTP 메서드와 무관하게 Illuminate\Http\Request 인스턴스에서 사용자 입력값 전체에 접근할 수 있습니다. HTTP 동사에 관계없이 input 메서드를 사용해 사용자 입력값을 조회할 수 있습니다.
$name = $request->input('name');input 메서드의 두 번째 인수로 기본값을 전달할 수 있습니다. 요청에 해당 입력값이 존재하지 않을 경우 이 값이 반환됩니다.
$name = $request->input('name', 'Sally');배열 형태의 입력값을 포함하는 폼을 다룰 때는 "점(dot) 표기법"을 사용해 배열에 접근할 수 있습니다.
$name = $request->input('products.0.name');
$names = $request->input('products.*.name');인수 없이 input 메서드를 호출하면, 입력값 전체를 연관 배열 형태로 조회할 수 있습니다.
$input = $request->input();쿼리 문자열에서 입력값 조회하기
input 메서드는 요청 페이로드 전체(쿼리 문자열 포함)에서 값을 조회하는 반면, query 메서드는 쿼리 문자열에서만 값을 조회합니다.
$name = $request->query('name');요청하는 쿼리 문자열 값 데이터가 존재하지 않을 경우, 이 메서드의 두 번째 인수가 반환됩니다.
$name = $request->query('name', 'Helen');인수 없이 query 메서드를 호출하면, 쿼리 문자열 값 전체를 연관 배열 형태로 조회할 수 있습니다.
$query = $request->query();JSON 입력값 조회하기
애플리케이션에 JSON 요청을 보낼 때, 요청의 Content-Type 헤더가 application/json으로 올바르게 설정되어 있다면 input 메서드를 통해 JSON 데이터에 접근할 수 있습니다. 점 표기법을 사용하면 JSON 배열/객체에 중첩된 값도 조회할 수 있습니다.
$name = $request->input('user.name');Stringable 입력값 조회하기
입력 데이터를 원시 string으로 조회하는 대신, string 메서드를 사용해 요청 데이터를 Illuminate\Support\Stringable 인스턴스로 조회할 수도 있습니다.
$name = $request->string('name')->trim();정수 입력값 조회하기
입력값을 정수로 조회하려면 integer 메서드를 사용할 수 있습니다. 이 메서드는 입력값을 정수로 변환하려고 시도하며, 변환할 수 없거나 값이 존재하지 않으면 지정한 기본값을 반환합니다. 이는 페이지 번호나 그 밖의 숫자형 입력값에 특히 유용합니다.
$perPage = $request->integer('per_page');불리언 입력값 조회하기
체크박스와 같은 HTML 요소를 다룰 때, 애플리케이션은 실제로는 문자열인 "참(truthy)" 값을 받게 될 수 있습니다. 예를 들어 "true" 또는 "on"입니다. 편의상 boolean 메서드를 사용하면 이러한 값을 불리언으로 조회할 수 있습니다. boolean 메서드는 1, "1", true, "true", "on", "yes"에 대해 true를 반환합니다. 그 외의 모든 값은 false를 반환합니다.
$archived = $request->boolean('archived');배열 입력값 조회하기
array, string, integer, boolean 입력값은 배열 접근 변수로도 접근할 수 있습니다.
$name = $request['name'];동적 프로퍼티를 통한 입력값 조회하기
Illuminate\Http\Request 인스턴스에서 동적 프로퍼티를 사용하여 사용자 입력값에 접근할 수도 있습니다. 예를 들어 애플리케이션 폼 중 하나에 name 필드가 있다면, 다음과 같이 해당 필드 값에 접근할 수 있습니다.
$name = $request->name;동적 프로퍼티를 사용할 때 라라벨은 먼저 요청 페이로드에서 해당 매개변수 값을 찾습니다. 없다면 매칭된 라우트의 매개변수들에서 해당 필드를 찾습니다.
입력 데이터 일부만 조회하기
입력 데이터의 일부만 조회하고 싶다면 only와 except 메서드를 사용할 수 있습니다. 두 메서드 모두 단일 array 또는 동적 목록의 인수를 받습니다.
$input = $request->only(['username', 'password']);
$input = $request->only('username', 'password');
$input = $request->except(['credit_card']);
$input = $request->except('credit_card');WARNING
only 메서드는 요청/입력값에 존재하는 키-값 쌍만 반환합니다. 요청에 존재하지 않는 키는 반환되지 않습니다.
입력값 존재 여부 확인
요청에 특정 값이 존재하는지 확인하려면 has 메서드를 사용할 수 있습니다. 요청에 해당 값이 존재하면 has 메서드는 true를 반환합니다.
if ($request->has('name')) {
// ...
}배열이 주어지면, has 메서드는 지정된 값 전부가 존재하는지 확인합니다.
if ($request->has(['name', 'email'])) {
// ...
}hasAny 메서드는 지정된 값 중 어느 하나라도 존재하면 true를 반환합니다.
if ($request->hasAny(['name', 'email'])) {
// ...
}whenHas 메서드는 요청에 값이 존재할 경우 주어진 클로저를 실행합니다.
$request->whenHas('name', function (string $input) {
// ...
});두 번째 클로저를 whenHas 메서드에 전달하면, 요청에 지정된 값이 존재하지 않을 때 이 클로저가 실행됩니다.
$request->whenHas('name', function (string $input) {
// "name" 값이 존재하는 경우...
}, function () {
// "name" 값이 존재하지 않는 경우...
});요청에 값이 존재하고 빈 문자열이 아님을 확인하고 싶다면 filled 메서드를 사용할 수 있습니다.
if ($request->filled('name')) {
// ...
}요청에 값이 없거나 빈 문자열인지 확인하고 싶다면 isNotFilled 메서드를 사용할 수 있습니다.
if ($request->isNotFilled('name')) {
// ...
}배열이 주어지면, isNotFilled 메서드는 지정된 값 전부가 없거나 빈 문자열인지 확인합니다.
if ($request->isNotFilled(['name', 'email'])) {
// ...
}anyFilled 메서드는 지정된 값 중 어느 하나라도 빈 문자열이 아니면 true를 반환합니다.
if ($request->anyFilled(['name', 'email'])) {
// ...
}whenFilled 메서드는 요청에 값이 존재하고 빈 문자열이 아닐 경우 주어진 클로저를 실행합니다.
$request->whenFilled('name', function (string $input) {
// ...
});두 번째 클로저를 whenFilled 메서드에 전달하면, 지정된 값이 "filled" 상태가 아닐 때 이 클로저가 실행됩니다.
$request->whenFilled('name', function (string $input) {
// "name" 값이 filled 상태인 경우...
}, function () {
// "name" 값이 filled 상태가 아닌 경우...
});주어진 키가 요청에 없는지 확인하려면 missing과 whenMissing 메서드를 사용할 수 있습니다.
$request->whenMissing('name', function () {
// "name" 값이 없는 경우...
}, function () {
// "name" 값이 있는 경우...
});입력값 추가 병합하기
때로는 요청의 기존 입력 데이터에 추가 입력값을 수동으로 병합해야 할 수도 있습니다. 이를 위해서는 merge 메서드를 사용할 수 있습니다. 주어진 입력 키가 이미 요청에 존재한다면, merge 메서드에 전달한 데이터로 덮어쓰입니다.
$request->merge(['votes' => 0]);mergeIfMissing 메서드는 요청 데이터에 해당 키가 아직 존재하지 않을 때만 입력값을 병합하는 데 사용할 수 있습니다.
$request->mergeIfMissing(['votes' => 0]);이전 입력값
라라벨은 다음 요청까지 하나의 요청에 대한 입력값을 유지할 수 있도록 지원합니다. 이 기능은 유효성 검증 오류가 발생한 후 폼을 다시 채우는 데 특히 유용합니다. 그러나 라라벨의 유효성 검증 기능을 사용한다면, 라라벨의 내장 유효성 검증 기능이 자동으로 이 세션 입력 플래시 필드를 활용할 수 있으므로, 직접 이 메서드를 사용할 필요가 없을 가능성이 높습니다.
입력값을 세션에 플래시하기
Illuminate\Http\Request 클래스의 flash 메서드는 현재 입력값을 세션에 플래시하여, 사용자가 애플리케이션에 다음 요청을 보낼 때 입력값을 사용할 수 있도록 합니다.
$request->flash();flashOnly와 flashExcept 메서드를 사용하면 요청 데이터 중 일부만 세션에 플래시할 수도 있습니다. 이 메서드들은 비밀번호와 같은 민감한 정보를 세션에서 제외할 때 유용합니다.
$request->flashOnly(['username', 'email']);
$request->flashExcept('password');입력값을 플래시한 후 리다이렉트하기
입력값을 세션에 플래시한 후 이전 페이지로 리다이렉트하는 경우가 많으므로, withInput 메서드를 사용하면 리다이렉트에 입력값 플래시를 간편하게 체이닝할 수 있습니다.
return redirect('form')->withInput();
return redirect()->route('user.create')->withInput();
return redirect('form')->withInput(
$request->except('password')
);이전 입력값 조회하기
이전 요청에서 플래시된 입력값을 조회하려면, Illuminate\Http\Request 인스턴스에서 old 메서드를 호출합니다. old 메서드는 이전에 플래시된 입력 데이터를 세션에서 가져옵니다.
$username = $request->old('username');라라벨은 전역 old 헬퍼도 제공합니다. Blade 템플릿에서 이전 입력값을 표시하는 경우, old 헬퍼를 사용하는 것이 더 편리합니다. 주어진 필드에 이전 입력값이 존재하지 않으면 null이 반환됩니다.
<input type="text" name="username" value="{{ old('username') }}">쿠키
요청에서 쿠키 조회하기
라라벨 프레임워크가 생성하는 모든 쿠키는 암호화되어 있으며 인증 코드로 서명되어 있으므로, 클라이언트에 의해 변경되면 유효하지 않은 것으로 간주됩니다. 요청에서 쿠키 값을 조회하려면, Illuminate\Http\Request 인스턴스에서 cookie 메서드를 사용합니다.
$value = $request->cookie('name');입력값 트리밍과 정규화
기본적으로 라라벨은 애플리케이션의 전역 미들웨어 스택에 Illuminate\Foundation\Http\Middleware\TrimStrings와 Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull 미들웨어를 포함시킵니다. 이 미들웨어들은 bootstrap/app.php 파일에 의해 애플리케이션의 전역 미들웨어 스택에 자동으로 추가됩니다. 이 미들웨어들은 요청에 들어오는 모든 문자열 필드를 자동으로 트리밍하며, 빈 문자열 필드를 null로 변환합니다. 이를 통해 라우트와 컨트롤러에서 이러한 정규화 문제를 신경 쓰지 않아도 됩니다.
이 동작을 비활성화하고 싶다면, trimStrings와 convertEmptyStringsToNull 메서드를 애플리케이션의 bootstrap/app.php 파일에서 호출하여 이 두 미들웨어를 애플리케이션의 미들웨어 스택에서 제거할 수 있습니다.
->withMiddleware(function (Middleware $middleware) {
$middleware->remove([
\Illuminate\Foundation\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
]);
})요청 중 일부에 대해서만 문자열 트리밍과 빈 문자열 변환을 비활성화하고 싶다면, bootstrap/app.php 파일에서 trimStrings와 convertEmptyStringsToNull 미들웨어 메서드를 사용할 수 있습니다. 두 메서드 모두 요청이 정규화 미들웨어를 건너뛰어야 하는지를 나타내는 true 또는 false를 반환하는 클로저의 배열을 인수로 받습니다.
->withMiddleware(function (Middleware $middleware) {
$middleware->convertEmptyStringsToNull(except: [
fn (Request $request) => $request->is('admin/*'),
]);
$middleware->trimStrings(except: [
fn (Request $request) => $request->is('admin/*'),
]);
})파일
업로드된 파일 조회하기
Illuminate\Http\Request 인스턴스에서 file 메서드 또는 동적 프로퍼티를 사용해 업로드된 파일을 조회할 수 있습니다. file 메서드는 PHP의 SplFileInfo 클래스를 확장한 Illuminate\Http\UploadedFile 클래스의 인스턴스를 반환하며, 파일과 상호작용할 수 있는 다양한 메서드를 제공합니다.
$file = $request->file('photo');
$file = $request->photo;요청에 file 메서드로 조회한 파일이 존재하는지 확인하려면 hasFile 메서드를 사용할 수 있습니다.
if ($request->hasFile('photo')) {
// ...
}업로드 성공 여부 검증하기
파일이 존재하는지 확인하는 것 외에도, isValid 메서드를 통해 파일 업로드에 문제가 없었는지 확인할 수 있습니다.
if ($request->file('photo')->isValid()) {
// ...
}파일 경로와 확장자
UploadedFile 클래스에는 파일의 전체 경로와 확장자에 접근할 수 있는 메서드도 포함되어 있습니다. extension 메서드는 파일 내용을 기반으로 파일의 확장자를 추정합니다. 이 확장자는 클라이언트가 제공한 확장자와 다를 수 있습니다.
$path = $request->photo->path();
$extension = $request->photo->extension();기타 파일 메서드
UploadedFile 인스턴스에는 다른 다양한 메서드들도 존재합니다. 이 클래스의 모든 메서드에 대한 자세한 정보는 클래스의 API 문서에서 확인할 수 있습니다.
업로드된 파일 저장하기
업로드된 파일을 저장하려면 일반적으로 설정되어 있는 파일시스템을 사용합니다. UploadedFile 클래스의 store 메서드는 업로드된 파일을 로컬 파일시스템이나 Amazon S3와 같은 클라우드 스토리지 위치 중 하나로 이동시킵니다.
store 메서드는 파일시스템 설정의 디스크 목록을 기준으로 한 상대 경로를 인수로 받습니다. 이 경로에는 파일명이 포함되지 않아도 되며, 고유한 ID가 파일명으로 자동 생성됩니다.
store 메서드는 두 번째 인수로 파일을 저장할 디스크 이름을 받습니다. 이 메서드는 디스크의 루트를 기준으로 한 파일 경로를 반환합니다.
$path = $request->photo->store('images');
$path = $request->photo->store('images', 's3');파일명이 자동으로 생성되는 것을 원하지 않는다면 storeAs 메서드를 사용할 수 있으며, 이 메서드는 경로, 파일명, 디스크 이름을 인수로 받습니다.
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');NOTE
라라벨의 파일 저장에 대한 더 자세한 내용은 파일시스템 문서 전체를 참고하세요.
신뢰할 수 있는 프록시 설정하기
TLS / SSL 인증서를 종료하는 로드 밸런서 뒤에서 애플리케이션을 실행할 때, url 헬퍼를 사용할 때 애플리케이션이 HTTPS 링크를 생성하지 않는 문제를 발견할 수도 있습니다. 이는 보통 애플리케이션이 로드 밸런서로부터 80 포트로 트래픽을 전달받고, 요청이 안전한 링크를 생성해야 한다는 사실을 알지 못하기 때문입니다.
이를 해결하기 위해 애플리케이션의 bootstrap/app.php 파일에 포함된 Illuminate\Http\Middleware\TrustProxies 미들웨어를 사용하여, 신뢰해야 할 로드 밸런서나 프록시를 빠르게 지정할 수 있습니다. 이를 통해 애플리케이션이 신뢰할 로드 밸런서나 프록시를 지정할 수 있으며, X-Forwarded-* 헤더를 통해 전달되는 요청 헤더로 어떤 것을 신뢰할지도 지정할 수 있습니다.
use Illuminate\Http\Middleware\TrustProxies;
use Illuminate\Http\Request;
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: [
'192.168.1.1',
'192.168.1.2',
]);
})신뢰할 프록시를 구성하는 것 외에도, 신뢰해야 할 프록시 헤더도 구성할 수 있습니다.
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(headers: Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB
);
})NOTE
AWS Elastic Load Balancing을 사용하는 경우, headers 값은 Request::HEADER_X_FORWARDED_AWS_ELB여야 합니다. 로드 밸런서가 AWS Elastic Load Balancing에서 사용하는 표준 Forwarded 확장 헤더를 사용하는 경우, headers 값은 Request::HEADER_X_FORWARDED_FOR여야 합니다. headers에 사용할 수 있는 상수에 대한 자세한 내용은 Symfony의 신뢰할 수 있는 프록시 처리 문서를 참고하세요.
모든 프록시 신뢰하기
AWS나 다른 "클라우드" 로드 밸런서 제공업체를 사용 중이어서 실제 밸런서의 IP 주소를 모를 수도 있습니다. 이런 경우 *를 사용하여 모든 프록시를 신뢰할 수 있습니다.
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: '*');
})신뢰할 수 있는 호스트 설정하기
기본적으로 라라벨은 받은 모든 HTTP 요청에 대해, 전달한 HTTP 요청의 Host 헤더 내용과 상관없이 응답합니다. 또한 웹 요청 중에 애플리케이션의 절대 URL을 생성할 때 Host 헤더의 값이 사용됩니다.
일반적으로는 Nginx나 Apache와 같은 웹 서버를 설정하여, 특정 호스트명과 일치하는 요청만 애플리케이션으로 전달하도록 해야 합니다. 하지만 웹 서버를 직접 커스터마이징할 수 없고 라라벨에게 특정 호스트명에만 응답하도록 지시해야 하는 경우, 애플리케이션에 Illuminate\Http\Middleware\TrustHosts 미들웨어를 활성화하면 됩니다.
TrustHosts 미들웨어는 애플리케이션의 bootstrap/app.php 파일에서 활성화할 수 있습니다. 이 메서드의 at 인수를 사용하여 애플리케이션이 응답해야 할 호스트명을 지정할 수 있습니다. Host 헤더가 다른 요청은 거부됩니다.
->withMiddleware(function (Middleware $middleware) {
$middleware->trustHosts(at: ['laravel.test']);
})기본적으로 애플리케이션의 URL 서브도메인에서 오는 요청도 자동으로 신뢰합니다. 이 동작을 비활성화하고 싶다면 subdomains 인수를 사용합니다.
->withMiddleware(function (Middleware $middleware) {
$middleware->trustHosts(at: ['laravel.test'], subdomains: false);
})애플리케이션 설정 파일에서 신뢰할 호스트를 동적으로 조회해야 한다면, at 인수에 클로저를 전달할 수 있습니다.
->withMiddleware(function (Middleware $middleware) {
$middleware->trustHosts(at: fn () => config('app.trusted_hosts'));
})NOTE
로컬 환경이나 테스트 환경에서 애플리케이션으로 전달되는 Host 헤더를 신뢰하지 않으려면, *.test와 같은 와일드카드 도메인을 사용하여 환경에 관계없이 모든 호스트명을 신뢰하도록 설정할 수 있습니다.
NOTE
request->url() 또는 request->fullUrl() 메서드를 호출하기 전에 host, httpHost, schemeAndHttpHost 메서드에 대한 자세한 내용은 위의 요청 호스트 조회하기 섹션을 참고하세요.
HTTP 요청
소개
라라벨의 Illuminate\Http\Request 클래스는 애플리케이션이 현재 처리 중인 HTTP 요청과 상호작용할 수 있는 객체지향적인 방법을 제공합니다. 이 클래스를 통해 요청과 함께 전달된 입력값, 쿠키, 파일 등을 쉽게 가져올 수 있습니다.
NOTE
Request 객체는 라라벨이 요청 수명 주기 전체에서 사용하는 핵심 객체입니다. 라우트 클로저나 컨트롤러 메서드의 파라미터로 타입힌트하기만 하면, 서비스 컨테이너가 자동으로 현재 요청 인스턴스를 주입해 줍니다. 별도로 인스턴스를 생성하거나 전역 변수를 사용할 필요가 없습니다.
요청과 상호작용하기
요청 인스턴스에 접근하기
의존성 주입을 통해 현재 HTTP 요청 인스턴스를 받으려면, 라우트 클로저나 컨트롤러 메서드에서 Illuminate\Http\Request 클래스를 타입힌트로 지정하면 됩니다. 들어오는 요청 인스턴스는 Laravel 서비스 컨테이너가 자동으로 주입해 줍니다:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 새로운 사용자를 저장합니다.
*/
public function store(Request $request): RedirectResponse
{
$name = $request->input('name');
// 사용자 저장 로직...
return redirect('/users');
}
}앞서 언급했듯, 라우트 클로저에서도 Illuminate\Http\Request 클래스를 타입힌트로 지정할 수 있습니다. 클로저가 실행될 때 서비스 컨테이너가 들어오는 요청을 자동으로 주입합니다:
use Illuminate\Http\Request;
Route::get('/', function (Request $request) {
// ...
});의존성 주입과 라우트 파라미터
컨트롤러 메서드가 라우트 파라미터로부터도 입력값을 받아야 한다면, 다른 의존성들 뒤에 라우트 파라미터를 나열해야 합니다. 예를 들어 라우트가 다음과 같이 정의되어 있다고 가정해 보겠습니다:
use App\Http\Controllers\UserController;
Route::put('/user/{id}', [UserController::class, 'update']);이 경우에도 Illuminate\Http\Request를 타입힌트로 지정하면서 동시에 id 라우트 파라미터에 접근하려면, 컨트롤러 메서드를 다음과 같이 정의하면 됩니다:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 지정된 사용자를 수정합니다.
*/
public function update(Request $request, string $id): RedirectResponse
{
// 사용자 수정 로직...
return redirect('/users');
}
}NOTE
타입힌트가 지정된 의존성(Request 등)이 먼저 오고, 그 뒤에 라우트 파라미터가 와야 한다는 순서를 꼭 기억하세요. 순서가 바뀌면 Laravel이 파라미터를 올바르게 매칭하지 못합니다.
요청 경로, 호스트, 메서드
Illuminate\Http\Request 인스턴스는 들어오는 HTTP 요청을 검사할 수 있는 다양한 메서드를 제공하며, Symfony\Component\HttpFoundation\Request 클래스를 확장한 것입니다. 그중 자주 사용되는 몇 가지를 살펴보겠습니다.
요청 경로 가져오기
path 메서드는 요청의 경로 정보를 반환합니다. 예를 들어 들어오는 요청이 http://example.com/foo/bar를 대상으로 한다면, path 메서드는 foo/bar를 반환합니다:
$uri = $request->path();요청 경로 / 라우트 검사하기
is 메서드를 사용하면 들어오는 요청 경로가 주어진 패턴과 일치하는지 확인할 수 있습니다. 이 메서드를 사용할 때 * 문자를 와일드카드로 사용할 수 있습니다:
if ($request->is('admin/*')) {
// ...
}routeIs 메서드를 사용하면 들어오는 요청이 이름이 지정된 라우트와 일치하는지 확인할 수 있습니다:
if ($request->routeIs('admin.*')) {
// ...
}요청 URL 가져오기
들어오는 요청의 전체 URL을 가져오려면 url 또는 fullUrl 메서드를 사용할 수 있습니다. url 메서드는 쿼리 스트링을 제외한 URL을 반환하고, fullUrl 메서드는 쿼리 스트링을 포함한 URL을 반환합니다:
$url = $request->url();
$urlWithQueryString = $request->fullUrl();현재 URL에 쿼리 스트링 데이터를 추가하고 싶다면 fullUrlWithQuery 메서드를 호출하면 됩니다. 이 메서드는 전달된 배열의 쿼리 스트링 변수를 현재 쿼리 스트링과 병합합니다:
$request->fullUrlWithQuery(['type' => 'phone']);특정 쿼리 스트링 파라미터를 제외한 현재 URL을 가져오고 싶다면 fullUrlWithoutQuery 메서드를 사용할 수 있습니다:
$request->fullUrlWithoutQuery(['type']);요청 호스트 가져오기
host, httpHost, schemeAndHttpHost 메서드를 통해 들어오는 요청의 "호스트" 정보를 가져올 수 있습니다:
// http://localhost:8000
$request->host(); // localhost
$request->httpHost(); // localhost:8000
$request->schemeAndHttpHost(); // http://localhost:8000요청 메서드 가져오기
method 메서드는 요청의 HTTP 동사(verb)를 반환합니다. isMethod 메서드를 사용하면 HTTP 동사가 주어진 문자열과 일치하는지 확인할 수 있습니다:
$method = $request->method();
if ($request->isMethod('post')) {
// ...
}요청 헤더
Illuminate\Http\Request 인스턴스의 header 메서드를 사용하면 요청 헤더 값을 가져올 수 있습니다. 해당 헤더가 요청에 존재하지 않으면 null이 반환됩니다. 다만 header 메서드는 두 번째 인수를 선택적으로 받을 수 있으며, 헤더가 없을 경우 이 값이 대신 반환됩니다:
$value = $request->header('X-Header-Name');
$value = $request->header('X-Header-Name', 'default');hasHeader 메서드를 사용하면 요청에 특정 헤더가 포함되어 있는지 확인할 수 있습니다:
if ($request->hasHeader('X-Header-Name')) {
// ...
}편의를 위해 Authorization 헤더에서 Bearer 토큰을 가져오는 bearerToken 메서드도 제공됩니다. 해당 헤더가 없다면 빈 문자열이 반환됩니다:
$token = $request->bearerToken();요청 IP 주소
ip 메서드를 사용하면 애플리케이션에 요청을 보낸 클라이언트의 IP 주소를 가져올 수 있습니다:
$ipAddress = $request->ip();프록시를 거쳐 전달된 모든 클라이언트 IP 주소를 배열 형태로 가져오고 싶다면 ips 메서드를 사용할 수 있습니다. 배열의 마지막 항목이 "원본" 클라이언트의 IP 주소입니다:
$ipAddresses = $request->ips();NOTE
IP 주소는 기본적으로 사용자가 조작할 수 있는, 신뢰할 수 없는 입력값이라는 점을 기억해 두세요. 로그 기록이나 통계 등 참고용으로만 사용하고, 인증이나 권한 검사와 같은 보안 로직에 그대로 사용하지 않는 것이 좋습니다.
콘텐츠 협상(Content Negotiation)
Laravel은 Accept 헤더를 통해 들어오는 요청이 어떤 콘텐츠 타입을 원하는지 확인할 수 있는 여러 메서드를 제공합니다. 먼저 getAcceptableContentTypes 메서드는 요청이 받아들일 수 있는 모든 콘텐츠 타입을 배열로 반환합니다:
$contentTypes = $request->getAcceptableContentTypes();accepts 메서드는 콘텐츠 타입 배열을 인수로 받아, 그중 하나라도 요청이 허용하는 타입이면 true를, 그렇지 않으면 false를 반환합니다:
if ($request->accepts(['text/html', 'application/json'])) {
// ...
}prefers 메서드를 사용하면 주어진 콘텐츠 타입 배열 중 요청이 가장 선호하는 타입이 무엇인지 확인할 수 있습니다. 제공된 콘텐츠 타입 중 어느 것도 요청이 허용하지 않으면 null이 반환됩니다:
$preferred = $request->prefers(['text/html', 'application/json']);대부분의 애플리케이션은 HTML 또는 JSON 중 하나만 응답으로 제공하므로, expectsJson 메서드를 사용하면 들어오는 요청이 JSON 응답을 기대하는지 빠르게 판단할 수 있습니다:
if ($request->expectsJson()) {
// ...
}AI 에이전트나 Markdown 형식의 응답을 소비하는 클라이언트를 지원하는 경우처럼, 요청이 Markdown을 특별히 선호하는지 혹은 다른 타입들과 함께 Markdown도 허용하는지 확인해야 할 때는 wantsMarkdown과 acceptsMarkdown 메서드를 사용할 수 있습니다:
if ($request->wantsMarkdown()) {
// 클라이언트가 가장 선호하는 콘텐츠 타입이 text/markdown인 경우...
}
if ($request->acceptsMarkdown()) {
// 클라이언트가 Markdown 응답을 허용하는 경우...
}PSR-7 요청
PSR-7 표준은 요청과 응답을 포함한 HTTP 메시지에 대한 인터페이스를 정의합니다. Laravel 요청 대신 PSR-7 요청 인스턴스를 사용하고 싶다면, 먼저 몇 가지 라이브러리를 설치해야 합니다. Laravel은 Symfony HTTP Message Bridge 컴포넌트를 사용해 일반적인 Laravel 요청과 응답을 PSR-7 호환 구현체로 변환합니다:
composer require symfony/psr-http-message-bridgecomposer require nyholm/psr7위 라이브러리들을 설치했다면, 라우트 클로저나 컨트롤러 메서드에서 요청 인터페이스를 타입힌트로 지정하여 PSR-7 요청을 가져올 수 있습니다:
use Psr\Http\Message\ServerRequestInterface;
Route::get('/', function (ServerRequestInterface $request) {
// ...
});NOTE
라우트나 컨트롤러에서 PSR-7 응답 인스턴스를 반환하면, 프레임워크가 이를 자동으로 Laravel 응답 인스턴스로 다시 변환하여 출력합니다.
입력값 조회하기
입력값 조회하기
전체 입력값 조회하기
all 메서드를 사용하면 들어온 요청의 모든 입력값을 array 형태로 가져올 수 있습니다. 이 메서드는 요청이 일반 HTML 폼에서 왔는지, XHR 요청인지 상관없이 동일하게 동작합니다:
$input = $request->all();collect 메서드를 사용하면 들어온 요청의 모든 입력값을 컬렉션 형태로 가져올 수도 있습니다:
$input = $request->collect();collect 메서드는 요청 입력값 중 일부만 컬렉션으로 가져오는 것도 가능합니다:
$request->collect('users')->each(function (string $user) {
// ...
});특정 입력값 조회하기
몇 가지 간단한 메서드를 사용하면 Illuminate\Http\Request 인스턴스에서 HTTP 메서드(GET, POST 등)에 관계없이 사용자 입력값에 접근할 수 있습니다. 어떤 HTTP 메서드로 요청이 왔든, input 메서드를 사용하면 입력값을 조회할 수 있습니다:
$name = $request->input('name');input 메서드의 두 번째 인자로 기본값을 전달할 수 있습니다. 해당 입력값이 요청에 존재하지 않을 경우 이 기본값이 반환됩니다:
$name = $request->input('name', 'Sally');배열 형태의 입력값을 가진 폼을 다룰 때는 "دات(dot)" 표기법을 사용해 배열에 접근할 수 있습니다:
$name = $request->input('products.0.name');
$names = $request->input('products.*.name');input 메서드를 인자 없이 호출하면, 모든 입력값을 연관 배열 형태로 가져올 수 있습니다:
$input = $request->input();쿼리 문자열에서 입력값 조회하기
input 메서드는 쿼리 문자열을 포함한 요청 페이로드 전체에서 값을 조회하는 반면, query 메서드는 쿼리 문자열에서만 값을 가져옵니다:
$name = $request->query('name');요청한 쿼리 문자열 값이 존재하지 않으면, 이 메서드의 두 번째 인자로 지정한 값이 반환됩니다:
$name = $request->query('name', 'Helen');query 메서드를 인자 없이 호출하면 모든 쿼리 문자열 값을 연관 배열 형태로 가져올 수 있습니다:
$query = $request->query();JSON 입력값 조회하기
애플리케이션에 JSON 요청을 보낼 때, 요청의 Content-Type 헤더가 application/json으로 올바르게 설정되어 있다면 input 메서드를 통해 JSON 데이터에 접근할 수 있습니다. JSON 배열이나 객체 내부에 중첩된 값을 가져올 때도 "닷(dot)" 표기법을 그대로 사용할 수 있습니다:
$name = $request->input('user.name');Stringable 형태로 입력값 조회하기
입력값을 기본 string 타입이 아니라 Illuminate\Support\Stringable 인스턴스로 받고 싶다면 string 메서드를 사용하면 됩니다:
$name = $request->string('name')->trim();정수 형태로 입력값 조회하기
입력값을 정수로 조회하려면 integer 메서드를 사용할 수 있습니다. 이 메서드는 입력값을 정수로 변환하려고 시도합니다. 입력값이 없으면 지정한 기본값을 반환합니다. 페이지네이션(pagination)이나 기타 숫자형 입력을 다룰 때 특히 유용합니다:
$perPage = $request->integer('per_page');불리언 형태로 입력값 조회하기
체크박스와 같은 HTML 요소를 다룰 때, 애플리케이션은 실제로는 문자열인 "참 같은(truthy)" 값을 받게 되는 경우가 많습니다. 예를 들어 "true"나 "on" 같은 값이죠. 이런 값을 불리언으로 변환해서 가져오고 싶다면 boolean 메서드를 사용하면 편리합니다. boolean 메서드는 1, "1", true, "true", "on", "yes" 값에 대해서는 true를 반환하고, 그 외의 모든 값에는 false를 반환합니다:
$archived = $request->boolean('archived');배열 형태로 입력값 조회하기
배열을 담고 있는 입력값은 array 메서드로 조회할 수 있습니다. 이 메서드는 항상 입력값을 배열로 변환합니다. 요청에 해당 이름의 입력값이 없다면 빈 배열이 반환됩니다:
$versions = $request->array('versions');날짜 형태로 입력값 조회하기
편의를 위해, 날짜/시간을 담고 있는 입력값은 date 메서드를 통해 Carbon 인스턴스로 조회할 수 있습니다. 요청에 해당 이름의 입력값이 없다면 null이 반환됩니다:
$birthday = $request->date('birthday');date 메서드의 두 번째, 세 번째 인자로 각각 날짜 형식과 타임존을 지정할 수 있습니다:
$elapsed = $request->date('elapsed', '!H:i', 'Europe/Madrid');입력값이 존재하지만 형식이 올바르지 않으면 InvalidArgumentException이 발생합니다. 따라서 date 메서드를 호출하기 전에 입력값을 검증(validate)하는 것을 권장합니다.
기간(Interval) 형태로 입력값 조회하기
기간을 나타내는 입력값은 interval 메서드를 사용해 CarbonInterval 인스턴스로 조회할 수 있습니다. 요청에 해당 이름의 입력값이 없다면 null이 반환됩니다:
$duration = $request->interval('duration');입력값이 숫자 형태라면, 두 번째 인자로 단위를 지정할 수 있습니다. 단위는 second, minute, day와 같은 문자열이나 Carbon\Unit enum 인스턴스를 사용할 수 있습니다:
use Carbon\Unit;
$timeout = $request->interval('timeout', 'second');
$delay = $request->interval('delay', Unit::Minute);입력값이 존재하지만 형식이 올바르지 않으면 InvalidArgumentException이 발생합니다. 따라서 interval 메서드를 호출하기 전에 입력값을 검증하는 것을 권장합니다.
Enum 형태로 입력값 조회하기
PHP enum에 대응하는 입력값도 요청에서 조회할 수 있습니다. 요청에 해당 이름의 입력값이 없거나, enum에 입력값과 일치하는 backing 값이 없다면 null이 반환됩니다. enum 메서드는 첫 번째 인자로 입력값의 이름을, 두 번째 인자로 enum 클래스를 받습니다:
use App\Enums\Status;
$status = $request->enum('status', Status::class);값이 없거나 올바르지 않을 때 반환할 기본값을 지정할 수도 있습니다:
$status = $request->enum('status', Status::class, Status::Pending);입력값이 PHP enum에 대응하는 값들의 배열이라면, enums 메서드를 사용해 enum 인스턴스로 구성된 배열을 가져올 수 있습니다:
use App\Enums\Product;
$products = $request->enums('products', Product::class);동적 속성으로 입력값 조회하기
Illuminate\Http\Request 인스턴스에서는 동적 속성을 통해서도 사용자 입력값에 접근할 수 있습니다. 예를 들어 애플리케이션의 어떤 폼에 name 필드가 있다면, 다음과 같이 값을 조회할 수 있습니다:
$name = $request->name;동적 속성을 사용할 때 Laravel은 먼저 요청 페이로드에서 해당 파라미터의 값을 찾습니다. 만약 존재하지 않으면, 매칭된 라우트의 파라미터에서 해당 필드를 찾습니다.
입력값 중 일부만 조회하기
입력값 중 일부만 조회해야 할 때는 only와 except 메서드를 사용할 수 있습니다. 두 메서드 모두 하나의 array를 인자로 받거나, 여러 개의 인자를 동적으로 나열해서 받을 수 있습니다:
$input = $request->only(['username', 'password']);
$input = $request->only('username', 'password');
$input = $request->except(['credit_card']);
$input = $request->except('credit_card');WARNING
only 메서드는 요청한 키/값 쌍만 반환합니다. 요청에 존재하지 않는 키/값 쌍은 반환하지 않는다는 점에 유의하세요.
입력값 존재 여부 확인하기
has 메서드를 사용하면 요청에 특정 값이 존재하는지 확인할 수 있습니다. 값이 요청에 존재하면 has 메서드는 true를 반환합니다:
if ($request->has('name')) {
// ...
}배열을 전달하면, has 메서드는 지정한 모든 값이 존재하는지 확인합니다:
if ($request->has(['name', 'email'])) {
// ...
}hasAny 메서드는 지정한 값들 중 하나라도 존재하면 true를 반환합니다:
if ($request->hasAny(['name', 'email'])) {
// ...
}whenHas 메서드는 요청에 값이 존재할 때 전달된 클로저를 실행합니다:
$request->whenHas('name', function (string $input) {
// ...
});whenHas 메서드에 두 번째 클로저를 전달하면, 지정한 값이 요청에 존재하지 않을 때 해당 클로저가 실행됩니다:
$request->whenHas('name', function (string $input) {
// "name" 값이 존재하는 경우...
}, function () {
// "name" 값이 존재하지 않는 경우...
});값이 요청에 존재하면서 빈 문자열이 아닌지 확인하려면 filled 메서드를 사용할 수 있습니다:
if ($request->filled('name')) {
// ...
}값이 요청에 없거나 빈 문자열인지 확인하려면 isNotFilled 메서드를 사용할 수 있습니다:
if ($request->isNotFilled('name')) {
// ...
}배열을 전달하면, isNotFilled 메서드는 지정한 모든 값이 없거나 비어 있는지 확인합니다:
if ($request->isNotFilled(['name', 'email'])) {
// ...
}anyFilled 메서드는 지정한 값들 중 하나라도 빈 문자열이 아니면 true를 반환합니다:
if ($request->anyFilled(['name', 'email'])) {
// ...
}whenFilled 메서드는 값이 요청에 존재하면서 빈 문자열이 아닐 때 전달된 클로저를 실행합니다:
$request->whenFilled('name', function (string $input) {
// ...
});whenFilled 메서드에 두 번째 클로저를 전달하면, 지정한 값이 "채워져 있지" 않을 때 해당 클로저가 실행됩니다:
$request->whenFilled('name', function (string $input) {
// "name" 값이 채워져 있는 경우...
}, function () {
// "name" 값이 채워져 있지 않은 경우...
});특정 키가 요청에 없는지 확인하려면 missing과 whenMissing 메서드를 사용할 수 있습니다:
if ($request->missing('name')) {
// ...
}
$request->whenMissing('name', function () {
// "name" 값이 없는 경우...
}, function () {
// "name" 값이 있는 경우...
});입력값에 데이터 병합하기
경우에 따라 요청에 이미 존재하는 입력 데이터에 추가 입력값을 수동으로 병합해야 할 때가 있습니다. 이럴 때는 merge 메서드를 사용하면 됩니다. 만약 지정한 입력 키가 이미 요청에 존재한다면, merge 메서드에 전달한 데이터로 덮어씁니다:
$request->merge(['votes' => 0]);mergeIfMissing 메서드는 해당 키가 요청의 입력 데이터에 존재하지 않을 때만 값을 병합합니다:
$request->mergeIfMissing(['votes' => 0]);이전 입력값 (Old Input)
Laravel에서는 한 요청의 입력값을 다음 요청에서도 사용할 수 있도록 유지하는 기능을 제공합니다. 이 기능은 유효성 검증 오류가 발생했을 때 폼에 입력했던 값을 다시 채워 넣는 데 특히 유용합니다. 다만 Laravel에 내장된 유효성 검증 기능을 사용한다면, 이 세션 입력값 플래시(flash) 메서드들을 직접 호출할 필요가 없는 경우가 많습니다. Laravel의 기본 유효성 검증 기능이 자동으로 처리해주기 때문입니다.
세션에 입력값 플래시하기
Illuminate\Http\Request 클래스의 flash 메서드는 현재 입력값을 세션에 플래시(flash)하여, 사용자의 다음 요청에서도 사용할 수 있게 해줍니다:
$request->flash();flashOnly와 flashExcept 메서드를 사용하면 요청 데이터 중 일부만 세션에 플래시할 수도 있습니다. 이 메서드들은 비밀번호와 같은 민감한 정보를 세션에 남기지 않도록 하는 데 유용합니다:
$request->flashOnly(['username', 'email']);
$request->flashExcept('password');입력값을 플래시하고 리다이렉트하기
입력값을 세션에 플래시한 다음 이전 페이지로 리다이렉트하는 작업은 자주 필요하므로, withInput 메서드를 사용해 리다이렉트에 체이닝(chaining)하면 간편하게 처리할 수 있습니다:
return redirect('/form')->withInput();
return redirect()->route('user.create')->withInput();
return redirect('/form')->withInput(
$request->except('password')
);이전 입력값 조회하기
이전 요청에서 플래시된 입력값을 조회하려면, Illuminate\Http\Request 인스턴스의 old 메서드를 호출하면 됩니다. old 메서드는 세션에 저장된 이전 입력값을 가져옵니다:
$username = $request->old('username');Laravel은 전역 old 헬퍼 함수도 제공합니다. Blade 템플릿 안에서 이전 입력값을 표시할 때는 폼에 값을 다시 채워 넣기 위해 이 old 헬퍼를 사용하는 것이 더 편리합니다. 해당 필드에 대한 이전 입력값이 없으면 null이 반환됩니다:
<input type="text" name="username" value="{{ old('username') }}">쿠키
요청에서 쿠키 조회하기
Laravel 프레임워크에서 생성된 모든 쿠키는 암호화되어 있으며 인증 코드로 서명되어 있습니다. 즉, 클라이언트가 값을 변경하면 그 쿠키는 유효하지 않은 것으로 처리됩니다. 요청에서 쿠키 값을 조회하려면, Illuminate\Http\Request 인스턴스의 cookie 메서드를 사용하세요:
$value = $request->cookie('name');입력값 트리밍과 정규화
라라벨은 기본적으로 애플리케이션의 전역 미들웨어 스택에 Illuminate\Foundation\Http\Middleware\TrimStrings와 Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull 미들웨어를 포함하고 있습니다. 이 두 미들웨어는 요청에 들어온 모든 문자열 필드의 앞뒤 공백을 자동으로 제거하고, 빈 문자열 필드는 null로 변환해 줍니다. 덕분에 라우트나 컨트롤러에서 이런 입력값 정규화 문제를 따로 신경 쓰지 않아도 됩니다.
NOTE
예를 들어 회원가입 폼에서 사용자가 이름 필드에 실수로 공백만 입력하고 제출하더라도, 해당 값은 자동으로 null로 변환됩니다. required 유효성 검사 규칙이 이런 상황을 자연스럽게 걸러낼 수 있는 이유입니다.
입력값 정규화 비활성화하기
모든 요청에 대해 이 동작을 비활성화하고 싶다면, 애플리케이션의 bootstrap/app.php 파일에서 $middleware->remove 메서드를 호출해 두 미들웨어를 미들웨어 스택에서 제거하면 됩니다.
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
use Illuminate\Foundation\Http\Middleware\TrimStrings;
->withMiddleware(function (Middleware $middleware): void {
$middleware->remove([
ConvertEmptyStringsToNull::class,
TrimStrings::class,
]);
})애플리케이션으로 들어오는 요청 중 일부에 대해서만 문자열 트리밍과 빈 문자열 변환을 비활성화하고 싶다면, bootstrap/app.php 파일에서 trimStrings와 convertEmptyStringsToNull 미들웨어 메서드를 사용하면 됩니다. 두 메서드는 모두 클로저 배열을 인자로 받으며, 각 클로저는 해당 요청에 대해 입력값 정규화를 건너뛸지 여부를 true 또는 false로 반환하면 됩니다.
->withMiddleware(function (Middleware $middleware): void {
$middleware->convertEmptyStringsToNull(except: [
fn (Request $request) => $request->is('admin/*'),
]);
$middleware->trimStrings(except: [
fn (Request $request) => $request->is('admin/*'),
]);
})Files (파일)
업로드된 파일 다루기
Illuminate\Http\Request 인스턴스에서 업로드된 파일을 가져올 때는 file 메서드나 동적 프로퍼티를 사용할 수 있습니다. file 메서드는 Illuminate\Http\UploadedFile 클래스의 인스턴스를 반환하는데, 이 클래스는 PHP의 SplFileInfo 클래스를 확장한 것으로 파일을 다루기 위한 다양한 메서드를 제공합니다:
$file = $request->file('photo');
$file = $request->photo;요청에 파일이 포함되어 있는지는 hasFile 메서드로 확인할 수 있습니다:
if ($request->hasFile('photo')) {
// ...
}업로드된 파일이 이미지이고 저장 전에 가공이 필요하다면, image 메서드를 사용해 Illuminate\Image\Image 인스턴스를 가져올 수 있습니다. 파일이 없는 경우에는 null이 반환됩니다:
$image = $request->image('photo');이미지 가공에 대해 더 알고 싶다면 이미지 가공 문서를 참고하세요.
업로드 성공 여부 검증하기
파일이 존재하는지 확인하는 것 외에도, isValid 메서드를 통해 업로드 과정에서 문제가 없었는지 검증할 수 있습니다:
if ($request->file('photo')->isValid()) {
// ...
}파일 경로와 확장자
UploadedFile 클래스는 파일의 전체 경로와 확장자를 가져오는 메서드도 제공합니다. extension 메서드는 파일의 실제 내용을 기반으로 확장자를 추측해서 반환하는데, 이는 클라이언트가 업로드 시 전달한 확장자와 다를 수 있다는 점에 유의하세요.
$path = $request->photo->path();
$extension = $request->photo->extension();NOTE
예를 들어 사용자가 profile.png라는 이름으로 파일을 업로드했더라도, 실제 파일 내용이 JPEG라면 extension 메서드는 jpg를 반환할 수 있습니다. 파일 확장자를 신뢰해야 하는 로직(예: 업로드 허용 여부 검증)이 있다면, 클라이언트가 보낸 확장자보다 이 메서드의 결과를 사용하는 것이 더 안전합니다.
기타 파일 메서드
UploadedFile 인스턴스에는 이 외에도 다양한 메서드가 존재합니다. 자세한 내용은 해당 클래스의 API 문서를 참고하세요.
업로드된 파일 저장하기
업로드된 파일을 저장할 때는 일반적으로 미리 설정해둔 파일시스템 중 하나를 사용합니다. UploadedFile 클래스의 store 메서드를 사용하면 업로드된 파일을 로컬 파일시스템이나 Amazon S3 같은 클라우드 스토리지 등 지정한 디스크로 옮길 수 있습니다.
store 메서드는 파일시스템에 설정된 루트 디렉터리를 기준으로 파일이 저장될 경로를 인자로 받습니다. 이 경로에는 파일명을 포함하지 않아도 되는데, 고유 ID가 자동으로 생성되어 파일명으로 사용되기 때문입니다.
또한 store 메서드는 파일을 저장할 디스크 이름을 두 번째 인자로 선택적으로 받을 수 있습니다. 이 메서드는 디스크의 루트 경로를 기준으로 한 파일의 상대 경로를 반환합니다:
$path = $request->photo->store('images');
$path = $request->photo->store('images', 's3');파일명이 자동으로 생성되는 것을 원하지 않는다면, 경로와 파일명, 디스크 이름을 인자로 받는 storeAs 메서드를 사용할 수 있습니다:
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');NOTE
라라벨의 파일 저장에 대해 더 자세히 알고 싶다면 파일 저장소 문서 전체를 참고하세요.
신뢰할 수 있는 프록시 설정
TLS/SSL 인증서를 처리하는 로드 밸런서 뒤에서 애플리케이션을 운영하다 보면, url 헬퍼가 HTTPS 링크를 생성해야 할 상황에서 간혹 HTTP 링크를 생성하는 문제를 겪을 수 있습니다. 이는 대부분 로드 밸런서가 80번 포트를 통해 애플리케이션으로 트래픽을 전달하기 때문에, 애플리케이션 입장에서는 실제로 보안 연결(HTTPS)이 사용되고 있다는 사실을 알 수 없어서 발생하는 문제입니다.
이 문제는 Laravel 애플리케이션에 기본 포함된 Illuminate\Http\Middleware\TrustProxies 미들웨어를 활성화해 해결할 수 있습니다. 이 미들웨어를 사용하면 애플리케이션이 신뢰해야 할 로드 밸런서나 프록시를 손쉽게 지정할 수 있습니다. 신뢰할 프록시는 bootstrap/app.php 파일에서 trustProxies 미들웨어 메서드를 통해 지정합니다.
->withMiddleware(function (Middleware $middleware): void {
$middleware->trustProxies(at: [
'192.168.1.1',
'10.0.0.0/8',
]);
})신뢰할 프록시 외에도, 신뢰할 프록시 헤더를 함께 설정할 수 있습니다.
->withMiddleware(function (Middleware $middleware): void {
$middleware->trustProxies(headers: Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB
);
})NOTE
AWS Elastic Load Balancing(ELB)을 사용 중이라면 headers 값으로 Request::HEADER_X_FORWARDED_AWS_ELB를 지정해야 합니다. 로드 밸런서가 RFC 7239에서 정의한 표준 Forwarded 헤더를 사용한다면 Request::HEADER_FORWARDED를 사용하면 됩니다. headers 값으로 사용할 수 있는 상수에 대한 자세한 내용은 Symfony의 프록시 신뢰 설정 문서를 참고하세요.
모든 프록시 신뢰하기
Amazon AWS와 같은 클라우드 로드 밸런서 서비스를 사용하는 경우, 실제 로드 밸런서의 IP 주소를 정확히 알기 어려울 수 있습니다. 이런 경우에는 *를 사용해 모든 프록시를 신뢰하도록 설정할 수 있습니다.
->withMiddleware(function (Middleware $middleware): void {
$middleware->trustProxies(at: '*');
})NOTE
모든 프록시를 신뢰하도록 설정하면 외부에서 위조한 헤더 값도 그대로 신뢰하게 됩니다. 운영 환경에서는 가능한 한 실제 로드 밸런서의 IP 대역을 명시적으로 지정하는 것이 안전합니다. 다만 AWS, GCP 등 IP 대역이 수시로 변경되는 환경에서는 * 설정이 현실적인 대안이 될 수 있습니다.
HTTP 요청
신뢰할 수 있는 호스트 설정하기
Laravel은 기본적으로 HTTP 요청의 Host 헤더 내용과 상관없이 자신이 받은 모든 요청에 응답합니다. 또한 웹 요청을 처리하는 동안 절대 URL을 생성할 때도 이 Host 헤더의 값을 그대로 사용합니다.
일반적으로는 Nginx나 Apache 같은 웹 서버를 설정해서 지정한 호스트명과 일치하는 요청만 애플리케이션으로 전달되도록 하는 것이 바람직합니다. 하지만 웹 서버 설정을 직접 건드릴 수 없는 환경이라면, Laravel 쪽에서 특정 호스트명에만 응답하도록 제한해야 할 수 있습니다. 이럴 때는 Illuminate\Http\Middleware\TrustHosts 미들웨어를 활성화하면 됩니다.
NOTE
공유 호스팅 서비스를 사용 중이거나, 리버스 프록시 앞단에 대한 설정 권한이 없는 경우에 특히 유용한 기능입니다.
TrustHosts 미들웨어를 활성화하려면, 애플리케이션의 bootstrap/app.php 파일에서 trustHosts 미들웨어 메서드를 호출하면 됩니다. 이 메서드의 at 인자를 사용해 애플리케이션이 응답해야 할 호스트명을 지정할 수 있습니다. 호스트명 문자열은 정규식으로 처리되며, 지정한 패턴과 일치하지 않는 Host 헤더를 가진 요청은 거부됩니다:
->withMiddleware(function (Middleware $middleware): void {
$middleware->trustHosts(at: ['^laravel\.test$']);
})기본적으로 애플리케이션 URL의 서브도메인에서 들어오는 요청도 자동으로 신뢰 대상에 포함됩니다. 이 동작을 비활성화하고 싶다면 subdomains 인자를 사용하세요:
->withMiddleware(function (Middleware $middleware): void {
$middleware->trustHosts(at: ['^laravel\.test$'], subdomains: false);
})신뢰할 호스트 목록을 결정하기 위해 애플리케이션의 설정 파일이나 데이터베이스에 접근해야 하는 경우에는, at 인자에 클로저를 전달할 수도 있습니다:
->withMiddleware(function (Middleware $middleware): void {
$middleware->trustHosts(at: fn () => config('app.trusted_hosts'));
})