Skip to content

Commit 2580a3c

Browse files
committed
Docs Auth gate usage with Laravel
1 parent d627c09 commit 2580a3c

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

guide/laravel-integration.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,107 @@ All AJAX handlers defined in the controller are available to every page action i
121121
::: tip
122122
For a deeper understanding of this pattern and how it compares to traditional resource controllers, see [Architecture & Philosophy](/guide/architecture).
123123
:::
124+
125+
## Authorization with Policies & Gates
126+
127+
Laravel's [authorization system](https://laravel.com/docs/authorization) works naturally inside AJAX handlers. Since handlers are regular controller methods, you can use `$this->authorize()`, the `Gate` facade, or any other authorization approach you'd use in a standard Laravel controller.
128+
129+
When authorization fails, the thrown exception is caught by the Larajax exception handler and returned as a clean AJAX error response — no extra configuration needed.
130+
131+
### Using Policies
132+
133+
Define a policy as you normally would:
134+
135+
```php
136+
// app/Policies/PostPolicy.php
137+
class PostPolicy
138+
{
139+
public function update(User $user, Post $post): bool
140+
{
141+
return $user->id === $post->user_id;
142+
}
143+
144+
public function delete(User $user, Post $post): bool
145+
{
146+
return $user->id === $post->user_id;
147+
}
148+
}
149+
```
150+
151+
Then call `$this->authorize()` inside your handlers:
152+
153+
```php
154+
class PostController extends LarajaxController
155+
{
156+
public function onUpdate()
157+
{
158+
$post = Post::findOrFail(request('id'));
159+
$this->authorize('update', $post);
160+
161+
$post->update(request()->validate([
162+
'title' => 'required',
163+
'body' => 'required',
164+
]));
165+
166+
return ['#post-' . $post->id => view('posts._row', compact('post'))];
167+
}
168+
169+
public function onDelete()
170+
{
171+
$post = Post::findOrFail(request('id'));
172+
$this->authorize('delete', $post);
173+
174+
$post->delete();
175+
176+
return ajax()->update(['#post-' . $post->id => ''])
177+
->flash('success', 'Post deleted.');
178+
}
179+
}
180+
```
181+
182+
If the user isn't authorized, Larajax returns an error response automatically:
183+
184+
```json
185+
{
186+
"__ajax": {
187+
"ok": false,
188+
"severity": "error",
189+
"message": "Access Denied"
190+
}
191+
}
192+
```
193+
194+
### Using Gates
195+
196+
You can also use the `Gate` facade for simpler, non-model checks:
197+
198+
```php
199+
use Illuminate\Support\Facades\Gate;
200+
201+
public function onPublish()
202+
{
203+
$post = Post::findOrFail(request('id'));
204+
205+
// Option 1: Throw on failure (caught automatically)
206+
Gate::authorize('publish', $post);
207+
208+
// Option 2: Check manually for a custom message
209+
if (Gate::denies('publish', $post)) {
210+
return ajax()->error('You cannot publish this post.');
211+
}
212+
213+
$post->update(['published' => true]);
214+
return ajax()->flash('success', 'Post published.');
215+
}
216+
```
217+
218+
### Route Middleware
219+
220+
For protecting an entire controller (both page loads and AJAX handlers), apply authorization middleware to the route:
221+
222+
```php
223+
Route::any('/admin/posts', [PostController::class, 'index'])
224+
->middleware('can:manage-posts');
225+
```
226+
227+
This blocks the request before the controller is reached, so no handler will execute for unauthorized users.

0 commit comments

Comments
 (0)