Laravel 인가 편집하기

경고: 로그인하지 않았습니다. 편집을 하면 IP 주소가 공개되게 됩니다. 로그인하거나 계정을 생성하면 편집자가 사용자 이름으로 기록되고, 다른 장점도 있습니다.

편집을 취소할 수 있습니다. 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 게시해주세요.

최신판 당신의 편집
55번째 줄: 55번째 줄:
</syntaxhighlight>
</syntaxhighlight>


===액션 인가===
===액션 인가===  
게이트를 사용하여 액션를 승인하려면, <code>Gate</code> 파사드가 제공하는 <code>allows</code> 또는 <code>denies</code> 메소드를 사용해야 합니다. 현재 인증된 사용자를 이 메소드에 전달할 필요는 없습니다. Laravel이 게이트 클로저로 사용자를 자동으로 전달하기 때문입니다. 인가가 필요한 액션을 수행하기 전에 애플리케이션의 컨트롤러에서 게이트 인가 메소드를 호출하는 것이 일반적입니다:
 
<syntaxhighlight lang='php'>
<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
 
class PostController extends Controller
{
    /**
    * 주어진 포스트를 업데이트합니다.
    */
    public function update(Request $request, Post $post): RedirectResponse
    {
        if (! Gate::allows('update-post', $post)) {
            abort(403);
        }
 
        // 포스트를 업데이트합니다...
 
        return redirect('/posts');
    }
}
</syntaxhighlight>
 
현재 인증된 사용자 외에 다른 사용자가 액션을 수행할 수 있는지 확인하려면 <code>Gate</code> 파사드의 <code>forUser</code> 메소드를 사용할 수 있습니다:
 
<syntaxhighlight lang='php'>
if (Gate::forUser($user)->allows('update-post', $post)) {
    // 사용자가 포스트를 업데이트할 수 있습니다...
}
 
if (Gate::forUser($user)->denies('update-post', $post)) {
    // 사용자가 포스트를 업데이트할 수 없습니다...
}
</syntaxhighlight>
 
한 번에 여러 액션을 인가하려면 <code>any</code> 또는 <code>none</code> 메소드를 사용할 수 있습니다:
 
<syntaxhighlight lang='php'>
if (Gate::any(['update-post', 'delete-post'], $post)) {
    // 사용자가 포스트를 업데이트하거나 삭제할 수 있습니다...
}
 
if (Gate::none(['update-post', 'delete-post'], $post)) {
    // 사용자가 포스트를 업데이트하거나 삭제할 수 없습니다...
}
</syntaxhighlight>
 
;예외를 던지며 인가
액션을 인가하려 시도하고 사용자가 주어진 행위를 수행할 수 없는 경우 <code>Illuminate\Auth\Access\AuthorizationException</code>을 자동으로 던지려면 <code>Gate</code> 퍼사드의 <code>authorize</code> 메소드를 사용할 수 있습니다. <code>AuthorizationException</code> 인스턴스는 Laravel에 의해 자동으로 403 HTTP 응답으로 변환됩니다:
 
<syntaxhighlight lang='php'>
Gate::authorize('update-post', $post);
 
// 액션이 인가되었습니다...
</syntaxhighlight>
 
;추가 컨텍스트 제공
인가 기능을 위한 게이트 메소드(<code>allow</code>, <code>deny</code>, <code>check</code>, <code>any</code>, <code>none</code>, <code>authorize</code>, <code>can</code>, <code>cannot</code>)와 인가 [[#Blade 템플릿을 통해|Blade 지시문]](<code>@can</code>, <code>@cannot</code>, <code>@canany</code>)은 두 번째 인수로 배열을 받을 수 있습니다. 이 배열 요소는 게이트 클로저에 매개변수로 전달되며, 인가 결정을 내릴 때 추가 컨텍스트로 사용할 수 있습니다:
 
<syntaxhighlight lang='php'>
use App\Models\Category;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
 
Gate::define('create-post', function (User $user, Category $category, bool $pinned) {
    if (! $user->canPublishToGroup($category->group)) {
        return false;
    } elseif ($pinned && ! $user->canPinPosts()) {
        return false;
    }
 
    return true;
});
 
if (Gate::check('create-post', [$category, $pinned])) {
    // 사용자가 포스트를 생성할 수 있습니다...
}
</syntaxhighlight>
 
===게이트 응답===
===게이트 응답===
지금까지는, 단순한 불리언 값을 반환하는 게이트만 살펴보았습니다. 하지만 때로는 오류 메시지를 포함한 더 자세한 응답을 반환하고 싶을 때가 있습니다. 이를 위해 게이트에서 <code>Illuminate\Auth\Access\Response</code>를 반환할 수 있습니다:
<syntaxhighlight lang='php'>
use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
Gate::define('edit-settings', function (User $user) {
    return $user->isAdmin
                ? Response::allow()
                : Response::deny('You must be an administrator.');
});
</syntaxhighlight>
게이트에서 인가 응답을 반환할 때에도 <code>Gate::allows</code> 메소드는 여전히 단순한 불리언 값을 반환하지만, <code>Gate::inspect</code> 메소드를 사용하여 게이트에서 반환된 전체 인가 응답을 얻을 수 있습니다:
<syntaxhighlight lang='php'>
$response = Gate::inspect('edit-settings');
if ($response->allowed()) {
    // 액션이 허가되었습니다...
} else {
    echo $response->message();
}
</syntaxhighlight>
게이트에서 인가되지 않은 액션에 대해 <code>AuthorizationException</code>을 던지는 <code>Gate::authorize</code> 메소드를 사용할 때, 인가 응답에서 제공한 오류 메시지는 HTTP 응답으로 전달됩니다:
<syntaxhighlight lang='php'>
Gate::authorize('edit-settings');
// 액션이 인가되었습니다...
</syntaxhighlight>
;HTTP 응답 상태 커스터마이징
게이트를 통해 액션이 거부될 때 403 HTTP 응답이 반환되지만, 때로는 대체 HTTP 상태 코드를 반환하는 것이 유용할 수 있습니다. 실패한 인가 확인에 대한 HTTP 상태 코드를 커스터마이징하려면 <code>Illuminate\Auth\Access\Response</code> 클래스의 <code>denyWithStatus</code> 정적 생성자를 사용할 수 있습니다:
<syntaxhighlight lang='php'>
use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
Gate::define('edit-settings', function (User $user) {
    return $user->isAdmin
                ? Response::allow()
                : Response::denyWithStatus(404);
});
</syntaxhighlight>
리소스를 404 응답으로 숨기는 것은 웹 애플리케이션에서 매우 흔한 패턴이기 때문에, 이를 위한 편리한 메소드인 <code>denyAsNotFound</code>가 제공됩니다:
<syntaxhighlight lang='php'>
use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
Gate::define('edit-settings', function (User $user) {
    return $user->isAdmin
                ? Response::allow()
                : Response::denyAsNotFound();
});
</syntaxhighlight>
===게이트 체크 가로채기===
===게이트 체크 가로채기===
때로는 특정 사용자에게 모든 권한을 부여하고자 할 때가 있습니다. <code>before</code> 메소드를 사용하여 다른 모든 권한 검사 전에 실행되는 클로저를 정의할 수 있습니다:
<syntaxhighlight lang='php'>
use App\Models\User;
use Illuminate\Support\Facades\Gate;
Gate::before(function (User $user, string $ability) {
    if ($user->isAdministrator()) {
        return true;
    }
});
</syntaxhighlight>
<code>before</code> 클로저가 null이 아닌 결과를 반환하면, 그 결과가 권한 검사 결과로 간주됩니다.
<code>after</code> 메소드를 사용하여 다른 모든 권한 검사 후에 실행되는 클로저를 정의할 수도 있습니다:
<syntaxhighlight lang='php'>
use App\Models\User;
Gate::after(function (User $user, string $ability, bool|null $result, mixed $arguments) {
    if ($user->isAdministrator()) {
        return true;
    }
});
</syntaxhighlight>
<code>before</code> 메소드와 마찬가지로, <code>after</code> 클로저가 null이 아닌 결과를 반환하면, 그 결과가 권한 검사 결과로 간주됩니다.
===인라인 인가===
===인라인 인가===
때로는, 특정 작업에 해당하는 전용 게이트를 작성하지 않고 현재 인증된 사용자가 주어진 작업을 수행할 권한이 있는지 확인하고 싶을 때가 있습니다. Laravel은 <code>Gate::allowIf</code>와 <code>Gate::denyIf</code> 메소드를 통해 이러한 유형의 "인라인" 인가를 수행할 수 있습니다. 인라인 인가는 정의된 [[#게이트 체크 가로채기|"before" 또는 "after" 인가 훅]]을 실행하지 않습니다:
<syntaxhighlight lang='php'>
use App\Models\User;
use Illuminate\Support\Facades\Gate;
Gate::allowIf(fn (User $user) => $user->isAdministrator());
Gate::denyIf(fn (User $user) => $user->banned());
</syntaxhighlight>
작업이 인가되지 않았거나 현재 인증된 사용자가 없는 경우, Laravel은 자동으로 <code>Illuminate\Auth\Access\AuthorizationException</code> 예외를 던집니다. <code>AuthorizationException</code> 인스턴스는 Laravel의 예외 처리기에 의해 자동으로 403 HTTP 응답으로 변환됩니다.
==정책 생성==
==정책 생성==
===정책 생성하기===
===정책 생성하기===
정책은 특정 모델이나 리소스와 관련된 인가 로직을 구성하는 클래스입니다. 예를 들어, 애플리케이션이 블로그라면, <code>App\Models\Post</code> 모델과 해당 모델에 대한 사용자 액션(예: 게시물 작성 또는 업데이트)을 승인하는 <code>App\Policies\PostPolicy</code>가 있을 수 있습니다.
<code>make:policy</code> Artisan 명령어를 사용하여 정책을 생성할 수 있습니다. 생성된 정책은 <code>app/Policies</code> 디렉토리에 배치됩니다. 이 디렉토리가 없으면 Laravel이 생성합니다:
<syntaxhighlight lang='bash'>
php artisan make:policy PostPolicy
</syntaxhighlight>
<code>make:policy</code> 명령어는 빈 정책 클래스를 생성합니다. 리소스 보기, 작성, 업데이트, 삭제와 관련된 예제 정책 메소드가 포함된 클래스를 생성하려면 명령을 실행할 때 <code>--model</code> 옵션을 제공할 수 있습니다:
<syntaxhighlight lang='bash'>
php artisan make:policy PostPolicy --model=Post
</syntaxhighlight>
===정책 등록하기===
===정책 등록하기===
;정책 발견
;정책 발견

제타위키에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-동일조건변경허락 3.0 라이선스로 배포된다는 점을 유의해 주세요(자세한 내용에 대해서는 제타위키:저작권 문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요.
또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다. 저작권이 있는 내용을 허가 없이 저장하지 마세요!

취소 편집 도움말 (새 창에서 열림)