본문 바로가기

URL 생성

번역일: 2026년 6월 20일

URL 생성

소개

Laravel은 애플리케이션 내에서 URL을 손쉽게 생성할 수 있는 다양한 헬퍼를 제공합니다. 이 헬퍼들은 Blade 템플릿이나 API 응답에서 링크를 만들 때, 또는 애플리케이션 내 다른 페이지로 리다이렉트 응답을 생성할 때 특히 유용합니다.

기본 사용법

URL 생성하기

url 헬퍼를 사용하면 임의의 URL을 생성할 수 있습니다. 생성된 URL은 현재 요청의 스킴(HTTP 또는 HTTPS)과 호스트를 자동으로 사용합니다.

$post = App\Models\Post::find(1); echo url("/posts/{$post->id}"); // http://example.com/posts/1

쿼리 스트링 파라미터를 포함한 URL을 만들려면 query 메서드를 사용하세요.

echo url()->query('/posts', ['search' => 'Laravel']); // https://example.com/posts?search=Laravel echo url()->query('/posts?sort=latest', ['search' => 'Laravel']); // http://example.com/posts?sort=latest&search=Laravel

경로에 이미 존재하는 쿼리 스트링 파라미터를 같은 키로 전달하면 기존 값을 덮어씁니다.

echo url()->query('/posts?sort=latest', ['sort' => 'oldest']); // http://example.com/posts?sort=oldest

배열 값도 쿼리 파라미터로 전달할 수 있습니다. 배열은 자동으로 적절하게 인코딩됩니다.

echo $url = url()->query('/posts', ['columns' => ['title', 'body']]); // http://example.com/posts?columns%5B0%5D=title&columns%5B1%5D=body echo urldecode($url); // http://example.com/posts?columns[0]=title&columns[1]=body

현재 URL 접근

url 헬퍼에 경로를 전달하지 않으면 Illuminate\Routing\UrlGenerator 인스턴스가 반환됩니다. 이를 통해 현재 URL 정보를 조회할 수 있습니다.

// 쿼리 스트링을 제외한 현재 URL echo url()->current(); // 쿼리 스트링을 포함한 현재 URL echo url()->full();

URL 파사드를 통해서도 동일하게 사용할 수 있습니다.

use Illuminate\Support\Facades\URL; echo URL::current();

이전 URL 접근

사용자가 직전에 방문한 URL이 필요한 경우, url 헬퍼의 previous 또는 previousPath 메서드를 사용할 수 있습니다.

// 이전 요청의 전체 URL echo url()->previous(); // 이전 요청의 경로만 echo url()->previousPath();

세션을 통해서는 이전 URL을 플루언트 URI 인스턴스로 가져올 수도 있습니다.

use Illuminate\Http\Request; Route::post('/users', function (Request $request) { $previousUri = $request->session()->previousUri(); // ... });

이전에 방문한 URL의 라우트 이름도 세션을 통해 조회할 수 있습니다.

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

이름 있는 라우트 URL

route 헬퍼를 사용하면 이름 있는 라우트에 대한 URL을 생성할 수 있습니다. 이름 있는 라우트의 장점은 실제 URL 경로가 변경되더라도 route 헬퍼를 호출하는 코드를 수정할 필요가 없다는 점입니다. 예를 들어 다음과 같이 라우트가 정의되어 있다고 가정합니다.

Route::get('/post/{post}', function (Post $post) { // ... })->name('post.show');

이 라우트의 URL은 다음과 같이 생성합니다.

echo route('post.show', ['post' => 1]); // http://example.com/post/1

파라미터가 여러 개인 라우트도 동일하게 사용할 수 있습니다.

Route::get('/post/{post}/comment/{comment}', function (Post $post, Comment $comment) { // ... })->name('comment.show'); echo route('comment.show', ['post' => 1, 'comment' => 3]); // http://example.com/post/1/comment/3

라우트 파라미터에 정의되지 않은 추가 키-값 쌍은 쿼리 스트링으로 자동 추가됩니다.

echo route('post.show', ['post' => 1, 'search' => 'rocket']); // http://example.com/post/1?search=rocket

Eloquent 모델

URL을 생성할 때 Eloquent 모델을 파라미터로 직접 전달할 수 있습니다. route 헬퍼가 모델의 라우트 키(일반적으로 기본 키)를 자동으로 추출합니다.

echo route('post.show', ['post' => $post]);

서명된 URL

Laravel은 이름 있는 라우트에 대한 "서명된(signed) URL"을 쉽게 생성할 수 있습니다. 서명된 URL은 쿼리 스트링에 서명 해시가 추가되며, 생성 이후 URL이 변조되지 않았는지 Laravel이 검증할 수 있습니다. 공개적으로 접근 가능하지만 URL 조작을 방지해야 하는 라우트에 특히 유용합니다.

예를 들어, 이메일로 발송하는 "수신 거부" 링크에 활용할 수 있습니다. URL 파사드의 signedRoute 메서드를 사용합니다.

use Illuminate\Support\Facades\URL; return URL::signedRoute('unsubscribe', ['user' => 1]);

absolute 인자를 false로 전달하면 서명 해시에서 도메인을 제외할 수 있습니다.

return URL::signedRoute('unsubscribe', ['user' => 1], absolute: false);

일정 시간 후 만료되는 임시 서명 URL이 필요하다면 temporarySignedRoute 메서드를 사용하세요. Laravel은 서명 URL을 검증할 때 인코딩된 만료 타임스탬프도 함께 확인합니다.

use Illuminate\Support\Facades\URL; return URL::temporarySignedRoute( 'unsubscribe', now()->plus(minutes: 30), ['user' => 1] );

서명된 라우트 요청 검증

들어오는 요청에 유효한 서명이 있는지 확인하려면 Illuminate\Http\Request 인스턴스의 hasValidSignature 메서드를 호출하세요.

use Illuminate\Http\Request; Route::get('/unsubscribe/{user}', function (Request $request) { if (! $request->hasValidSignature()) { abort(401); } // ... })->name('unsubscribe');

클라이언트 측 페이지네이션처럼 프론트엔드에서 서명된 URL에 파라미터를 추가해야 하는 경우도 있습니다. 이때는 hasValidSignatureWhileIgnoring 메서드를 사용하여 검증 시 무시할 쿼리 파라미터를 지정할 수 있습니다. 단, 무시하도록 지정한 파라미터는 누구든지 자유롭게 변경할 수 있다는 점에 유의하세요.

if (! $request->hasValidSignatureWhileIgnoring(['page', 'order'])) { abort(401); }

요청 인스턴스로 직접 검증하는 대신, signed 미들웨어(Illuminate\Routing\Middleware\ValidateSignature)를 라우트에 지정할 수도 있습니다. 유효한 서명이 없는 요청이 들어오면 미들웨어가 자동으로 403 HTTP 응답을 반환합니다.

Route::post('/unsubscribe/{user}', function (Request $request) { // ... })->name('unsubscribe')->middleware('signed');

서명된 URL이 해시에 도메인을 포함하지 않는 경우, 미들웨어에 relative 인자를 전달해야 합니다.

Route::post('/unsubscribe/{user}', function (Request $request) { // ... })->name('unsubscribe')->middleware('signed:relative');

유효하지 않은 서명 URL에 대한 응답 커스터마이징

만료된 서명 URL에 접근하면 기본적으로 403 상태 코드의 일반 오류 페이지가 표시됩니다. bootstrap/app.php 파일에서 InvalidSignatureException 예외에 대한 커스텀 렌더 클로저를 정의하여 이 동작을 원하는 대로 변경할 수 있습니다.

use Illuminate\Routing\Exceptions\InvalidSignatureException; ->withExceptions(function (Exceptions $exceptions): void { $exceptions->render(function (InvalidSignatureException $e) { return response()->view('errors.link-expired', status: 403); }); })

컨트롤러 액션 URL

action 함수를 사용하면 특정 컨트롤러 액션에 대한 URL을 생성할 수 있습니다.

use App\Http\Controllers\HomeController; $url = action([HomeController::class, 'index']);

컨트롤러 메서드가 라우트 파라미터를 받는 경우, 두 번째 인자로 연관 배열을 전달합니다.

$url = action([UserController::class, 'profile'], ['id' => 1]);

플루언트 URI 객체

Laravel의 Uri 클래스는 URI를 객체 형태로 편리하게 생성하고 조작할 수 있는 플루언트 인터페이스를 제공합니다. 이 클래스는 내부적으로 League URI 패키지를 래핑하며 Laravel 라우팅 시스템과 자연스럽게 통합됩니다.

다음과 같은 정적 메서드로 Uri 인스턴스를 생성할 수 있습니다.

use App\Http\Controllers\UserController; use App\Http\Controllers\InvokableController; use Illuminate\Support\Uri; // 문자열로부터 URI 인스턴스 생성 $uri = Uri::of('https://example.com/path'); // 경로, 이름 있는 라우트, 컨트롤러 액션으로부터 생성 $uri = Uri::to('/dashboard'); $uri = Uri::route('users.show', ['user' => 1]); $uri = Uri::signedRoute('users.show', ['user' => 1]); $uri = Uri::temporarySignedRoute('user.index', now()->plus(minutes: 5)); $uri = Uri::action([UserController::class, 'index']); $uri = Uri::action(InvokableController::class); // 현재 요청 URL로부터 URI 인스턴스 생성 $uri = $request->uri(); // 이전 요청 URL로부터 URI 인스턴스 생성 $uri = $request->session()->previousUri();

URI 인스턴스를 생성한 후에는 메서드 체이닝으로 값을 변경할 수 있습니다.

$uri = Uri::of('https://example.com') ->withScheme('http') ->withHost('test.com') ->withPort(8000) ->withPath('/users') ->withQuery(['page' => 2]) ->withFragment('section-1');

플루언트 URI 객체에 대한 더 자세한 내용은 URI 문서를 참고하세요.

기본값 설정

일부 애플리케이션에서는 특정 URL 파라미터에 대해 요청 전체에서 사용할 기본값을 지정하고 싶을 수 있습니다. 예를 들어, 많은 라우트에서 {locale} 파라미터를 사용한다고 가정합니다.

Route::get('/{locale}/posts', function () { // ... })->name('post.index');

route 헬퍼를 호출할 때마다 locale을 매번 전달하는 것은 번거롭습니다. URL::defaults 메서드를 사용하면 이 파라미터의 기본값을 현재 요청 동안 전역으로 적용할 수 있습니다. 현재 요청에 접근할 수 있도록 라우트 미들웨어에서 호출하는 것이 일반적입니다.

<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\URL; use Symfony\Component\HttpFoundation\Response; class SetDefaultLocaleForUrls { /** * 들어오는 요청을 처리합니다. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next): Response { URL::defaults(['locale' => $request->user()->locale]); return $next($request); } }

locale 파라미터의 기본값이 설정되면, 이후 route 헬퍼를 호출할 때 해당 값을 따로 전달할 필요가 없습니다.

URL 기본값과 미들웨어 우선순위

URL 기본값을 설정하는 미들웨어는 Laravel의 암묵적 모델 바인딩(implicit model binding) 처리에 영향을 줄 수 있습니다. 따라서 URL 기본값을 설정하는 미들웨어는 Laravel 내장 SubstituteBindings 미들웨어보다 먼저 실행되도록 미들웨어 우선순위를 지정해야 합니다. bootstrap/app.php 파일에서 priority 미들웨어 메서드를 사용해 설정할 수 있습니다.

->withMiddleware(function (Middleware $middleware): void { $middleware->prependToPriorityList( before: \Illuminate\Routing\Middleware\SubstituteBindings::class, prepend: \App\Http\Middleware\SetDefaultLocaleForUrls::class, ); })

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

번역일: 2026년 6월 20일