lt;pgt;Ở các bài trước, chúng ta đã cài đặt lt;stronggt;Laravel Breezelt;/stronggt;, đăng ký tài khoản và đăng nhập vào hệ thống.lt;/pgt;lt;pgt;Tuy nhiên, hiện tại nếu người dùng biết đường dẫn trực tiếp như:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;/posts/create
lt;/codegt;lt;/pregt;lt;pgt;hoặc:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;/dashboard
lt;/codegt;lt;/pregt;lt;pgt;thì liệu họ có thể truy cập được hay không?lt;/pgt;lt;pgt;Đó chính là nhiệm vụ của lt;stronggt;Middlewarelt;/stronggt;.lt;/pgt;lt;pgt;Middleware đóng vai trò như một lt;stronggt;lớp bảo vệlt;/stronggt;, kiểm tra mọi yêu cầu trước khi cho phép truy cập vào Controller hoặc Route.lt;/pgt;lt;hr /gt;lt;h1gt;Middleware là gì?lt;/h1gt;lt;pgt;Middleware là đoạn mã nằm giữa lt;stronggt;Requestlt;/stronggt; và lt;stronggt;Controllerlt;/stronggt;.lt;/pgt;lt;pgt;Mọi yêu cầu gửi đến Laravel đều có thể đi qua một hoặc nhiều Middleware.lt;/pgt;lt;pgt;Sơ đồ:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;Người dùng
│
▼
HTTP Request
│
▼
Middleware
│
▼
Controller
│
▼
Response
lt;/codegt;lt;/pregt;lt;pgt;Nếu Middleware từ chối yêu cầu, Controller sẽ không được thực thi.lt;/pgt;lt;pgt;lt;/pgt;lt;div class=quot;separatorquot; style=quot;clear: both; text-align: center;quot;gt;lt;a href=quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfHhQOZL1KMyZkm3JcjKHnKiamxgttt0W-t6-RVhTkuwmKIfZ6WjlapgdbBEO7BKwvU07xsalqssg7rLXykihpd17BOmChACrK_5Y4BwHC4ebLfFYNz8b2wTli7bIZ0k8GgPbFPafjTWZobGkCpS8bS809qvAd52ZrpN5Kfu3ivcW1jT-1vjDmHqA8ZBc/s1536/bai24.pngquot; style=quot;margin-left: 1em; margin-right: 1em;quot;gt;lt;img border=quot;0quot; data-original-height=quot;1024quot; data-original-width=quot;1536quot; height=quot;213quot; src=quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfHhQOZL1KMyZkm3JcjKHnKiamxgttt0W-t6-RVhTkuwmKIfZ6WjlapgdbBEO7BKwvU07xsalqssg7rLXykihpd17BOmChACrK_5Y4BwHC4ebLfFYNz8b2wTli7bIZ0k8GgPbFPafjTWZobGkCpS8bS809qvAd52ZrpN5Kfu3ivcW1jT-1vjDmHqA8ZBc/s320/bai24.pngquot; width=quot;320quot; /gt;lt;/agt;lt;spangt;lt;a name=#39;more#39;gt;lt;/agt;lt;/spangt;lt;/divgt;lt;pgt;lt;/pgt;lt;hr /gt;lt;h1gt;Ví dụ thực tếlt;/h1gt;lt;pgt;Giả sử Blog có các chức năng:lt;/pgt;lt;ulgt;lt;ligt;lt;pgt;Xem bài viết.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Thêm bài viết.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Chỉnh sửa bài viết.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Xóa bài viết.lt;/pgt;lt;/ligt;lt;/ulgt;lt;pgt;Khách chưa đăng nhập:lt;/pgt;lt;pgt;✅ Được xem bài viết.lt;/pgt;lt;pgt;❌ Không được tạo bài viết.lt;/pgt;lt;pgt;❌ Không được sửa bài viết.lt;/pgt;lt;pgt;❌ Không được xóa bài viết.lt;/pgt;lt;pgt;Middleware sẽ đảm nhận việc kiểm tra này.lt;/pgt;lt;hr /gt;lt;h1gt;Middleware authlt;/h1gt;lt;pgt;Laravel đã có sẵn Middleware:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;auth
lt;/codegt;lt;/pregt;lt;pgt;Nó sẽ kiểm tra:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;Người dùng đã đăng nhập?
│
Có Không
│ │
▼ ▼
Cho phép Chuyển Login
lt;/codegt;lt;/pregt;lt;hr /gt;lt;h1gt;Bảo vệ Routelt;/h1gt;lt;pgt;Ví dụ:lt;/pgt;lt;pregt;lt;code class=quot;language-phpquot;gt;use App\Http\Controllers\PostController;
Route::middleware(#39;auth#39;)-gt;group(function () {
Route::resource(
#39;posts#39;,
PostController::class
);
});
lt;/codegt;lt;/pregt;lt;pgt;Toàn bộ các Route của lt;code inline=quot;quot;gt;PostControllerlt;/codegt; đều yêu cầu đăng nhập.lt;/pgt;lt;hr /gt;lt;h1gt;Chỉ bảo vệ một Routelt;/h1gt;lt;pgt;Ví dụ:lt;/pgt;lt;pregt;lt;code class=quot;language-phpquot;gt;Route::get(
#39;/dashboard#39;,
function () {
return view(#39;dashboard#39;);
}
)-gt;middleware(#39;auth#39;);
lt;/codegt;lt;/pregt;lt;pgt;Nếu chưa đăng nhập, Laravel sẽ chuyển người dùng đến trang Login.lt;/pgt;lt;hr /gt;lt;h1gt;Kiểm tralt;/h1gt;lt;pgt;Đăng xuất khỏi hệ thống.lt;/pgt;lt;pgt;Sau đó truy cập:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;/posts/create
lt;/codegt;lt;/pregt;lt;pgt;Kết quả:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;302 Redirect
↓
/login
lt;/codegt;lt;/pregt;lt;pgt;Đây là hành vi mặc định của Middleware lt;code inline=quot;quot;gt;authlt;/codegt;.lt;/pgt;lt;hr /gt;lt;h1gt;Kết hợp với Breezelt;/h1gt;lt;pgt;Sau khi cài Laravel Breeze, Route lt;code inline=quot;quot;gt;dashboardlt;/codegt; thường được bảo vệ như sau:lt;/pgt;lt;pregt;lt;code class=quot;language-phpquot;gt;Route::get(#39;/dashboard#39;, function () {
return view(#39;dashboard#39;);
})-gt;middleware([#39;auth#39;]);
lt;/codegt;lt;/pregt;lt;pgt;Điều này đảm bảo chỉ người dùng đã xác thực mới truy cập được.lt;/pgt;lt;hr /gt;lt;h1gt;Middleware guestlt;/h1gt;lt;pgt;Laravel cũng có Middleware:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;guest
lt;/codegt;lt;/pregt;lt;pgt;Ý nghĩa:lt;/pgt;lt;ulgt;lt;ligt;lt;pgt;Chưa đăng nhập → được truy cập.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Đã đăng nhập → chuyển hướng.lt;/pgt;lt;/ligt;lt;/ulgt;lt;pgt;Ví dụ:lt;/pgt;lt;pregt;lt;code class=quot;language-phpquot;gt;Route::middleware(#39;guest#39;)-gt;group(function () {
Route::get(
#39;/login#39;,
...
);
Route::get(
#39;/register#39;,
...
);
});
lt;/codegt;lt;/pregt;lt;pgt;Người đã đăng nhập( k phải lt;bgt;guestlt;/bgt;) sẽ không thể mở lại trang Login hoặc Register.lt;/pgt;lt;hr /gt;lt;h1gt;Middleware nhiều lớplt;/h1gt;lt;pgt;Một Route có thể sử dụng nhiều Middleware.lt;/pgt;lt;pgt;Ví dụ:lt;/pgt;lt;pregt;lt;code class=quot;language-phpquot;gt;Route::middleware([
#39;auth#39;,
#39;verified#39;,
])-gt;group(function () {
//
});
lt;/codegt;lt;/pregt;lt;pgt;Laravel sẽ kiểm tra lần lượt:lt;/pgt;lt;ulgt;lt;ligt;lt;pgt;Đã đăng nhập.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Email đã xác minh.lt;/pgt;lt;/ligt;lt;/ulgt;lt;pgt;Nếu một bước không đạt, yêu cầu sẽ bị chặn.lt;/pgt;lt;hr /gt;lt;h1gt;Tạo Middleware mớilt;/h1gt;lt;pgt;Tạo bằng Artisan:lt;/pgt;lt;pregt;lt;code class=quot;language-bashquot;gt;php artisan make:middleware CheckPostOwner
lt;/codegt;lt;/pregt;lt;pgt;Laravel sẽ tạo:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;app/
└── Http/
└── Middleware/
CheckPostOwner.php
lt;/codegt;lt;/pregt;lt;hr /gt;lt;h1gt;Ví dụ Middlewarelt;/h1gt;lt;pregt;lt;code class=quot;language-phpquot;gt;public function handle(
Request $request,
Closure $next
)
{
if (!auth()-gt;check()) {
return redirect()
-gt;route(#39;login#39;);
}
return $next($request);
}
lt;/codegt;lt;/pregt;lt;pgt;lt;code inline=quot;quot;gt;$next($request)lt;/codegt; nghĩa là cho phép Request tiếp tục đi tới Controller.lt;/pgt;lt;hr /gt;lt;h1gt;Chỉ cho tác giả sửa bàilt;/h1gt;lt;pgt;Giả sử mỗi Post có:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;user_id
lt;/codegt;lt;/pregt;lt;pgt;Middleware:lt;/pgt;lt;pregt;lt;code class=quot;language-phpquot;gt;$post = $request-gt;route(#39;post#39;);
if (
$post-gt;user_id != auth()-gt;id()
) {
abort(403);
}
return $next($request);
lt;/codegt;lt;/pregt;lt;pgt;Nếu người dùng không phải là tác giả:lt;/pgt;
lt;pregt;lt;code class=quot;language-textquot;gt;403 Forbidden
lt;/codegt;lt;/pregt;lt;pgt;Đây là cách bảo vệ dữ liệu rất phổ biến trong Blog CMS.lt;/pgt;lt;hr /gt;lt;h1gt;Áp dụng cho Profilelt;/h1gt;lt;pgt;Chú ý: ví dụ này chỉ minh họa vì Breeze thiết kế để mỗi user chỉ nhìn thấy profile của chính mình nên k cần middleware.lt;/pgt;lt;pgt;trước khi chạy link /profile nên dùng lệnh tạo CategoryController trước (do đã khai báo trong route nhưng chưa tạo dẫn đến lỗi trong route:list)lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;/profile/5/edit
lt;/codegt;lt;/pregt;lt;pgt;Middleware kiểm tra:lt;/pgt;lt;pregt;lt;code class=quot;language-phpquot;gt;$profile = $request
-gt;route(#39;profile#39;);
if (
$profile-gt;user_id != auth()-gt;id()
) {
abort(403);
}
lt;/codegt;lt;/pregt;lt;pgt;Người dùng chỉ được sửa Profile của chính mình.lt;/pgt;lt;hr /gt;lt;h1gt;Middleware trong thực tếlt;/h1gt;lt;pgt;Một số Middleware thường gặp:lt;/pgt;lt;tablegt;lt;theadgt;lt;trgt;lt;thgt;Middlewarelt;/thgt;lt;thgt;Chức nănglt;/thgt;lt;/trgt;lt;/theadgt;lt;tbodygt;lt;trgt;lt;tdgt;authlt;/tdgt;lt;tdgt;Kiểm tra đăng nhậplt;/tdgt;lt;/trgt;lt;trgt;lt;tdgt;guestlt;/tdgt;lt;tdgt;Chỉ cho khách truy cậplt;/tdgt;lt;/trgt;lt;trgt;lt;tdgt;verifiedlt;/tdgt;lt;tdgt;Email đã xác minhlt;/tdgt;lt;/trgt;lt;trgt;lt;tdgt;throttlelt;/tdgt;lt;tdgt;Giới hạn số lần gửi Requestlt;/tdgt;lt;/trgt;lt;trgt;lt;tdgt;signedlt;/tdgt;lt;tdgt;Kiểm tra URL có chữ kýlt;/tdgt;lt;/trgt;lt;trgt;lt;tdgt;customlt;/tdgt;lt;tdgt;Middleware tự tạolt;/tdgt;lt;/trgt;lt;/tbodygt;lt;/tablegt;lt;hr /gt;lt;h1gt;Middleware và Requestlt;/h1gt;lt;pgt;Quy trình xử lý:lt;/pgt;lt;pregt;lt;code class=quot;language-textquot;gt;Request
│
▼
Middleware
│
▼
Validation
│
▼
Controller
│
▼
Model
│
▼
Database
lt;/codegt;lt;/pregt;lt;pgt;Middleware luôn hoạt động trước Controller.lt;/pgt;lt;hr /gt;lt;h1gt;Tổng kếtlt;/h1gt;lt;pgt;Trong bài này chúng ta đã học:lt;/pgt;lt;ulgt;lt;ligt;lt;pgt;Middleware là gì.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Middleware lt;code inline=quot;quot;gt;authlt;/codegt;.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Middleware lt;code inline=quot;quot;gt;guestlt;/codegt;.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Bảo vệ Route.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Route Group.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Tạo Middleware bằng Artisan.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;lt;code inline=quot;quot;gt;$next($request)lt;/codegt;.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;lt;code inline=quot;quot;gt;abort(403)lt;/codegt;.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Kiểm tra chủ sở hữu của Post và Profile.lt;/pgt;lt;/ligt;lt;/ulgt;lt;pgt;Middleware là tuyến phòng thủ đầu tiên của ứng dụng Laravel, giúp bảo vệ các chức năng quan trọng trước khi dữ liệu được xử lý.lt;/pgt;lt;hr /gt;lt;h1gt;Bài tậplt;/h1gt;lt;olgt;lt;ligt;lt;pgt;Bảo vệ toàn bộ Route lt;code inline=quot;quot;gt;postslt;/codegt; bằng Middleware lt;code inline=quot;quot;gt;authlt;/codegt;.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Kiểm tra truy cập lt;code inline=quot;quot;gt;/dashboardlt;/codegt; khi chưa đăng nhập.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Tạo Middleware lt;code inline=quot;quot;gt;CheckPostOwnerlt;/codegt;.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Chỉ cho phép tác giả sửa hoặc xóa bài viết của mình.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Áp dụng Middleware cho chức năng chỉnh sửa Profile.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Thử truy cập bằng tài khoản khác và quan sát kết quả lt;code inline=quot;quot;gt;403 Forbiddenlt;/codegt;.lt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Kết hợp lt;code inline=quot;quot;gt;authlt;/codegt; và lt;code inline=quot;quot;gt;verifiedlt;/codegt; cho một Route bất kỳ.lt;/pgt;lt;/ligt;lt;/olgt;lt;hr /gt;lt;h2gt;Bài tiếp theolt;/h2gt;lt;pgt;Ở lt;stronggt;Bài 25lt;/stronggt;, chúng ta sẽ tìm hiểu lt;stronggt;Authorizationlt;/stronggt;, cơ chế phân quyền trong Laravel bằng lt;stronggt;Gatelt;/stronggt; và lt;stronggt;Policylt;/stronggt;, giúp xác định lt;stronggt;ai được phép thực hiện hành động nàolt;/stronggt; trên từng đối tượng dữ liệu như Post, User hoặc Category.lt;/pgt;
lt;hr /gt;
lt;h1gt;BONUSlt;/h1gt;
lt;pgt;Phần view posts (hiện tại mới xây dựng có search theo category)lt;/pgt;
lt;pgt;Có thể dùng CDN.lt;/pgt;
lt;pregt;lt;codegt;lt;link rel=quot;stylesheetquot;
href=quot;https://cdn.datatables.net/2.3.4/css/dataTables.dataTables.min.cssquot;gt;
lt;script src=quot;https://code.jquery.com/jquery-3.7.1.min.jsquot;gt;lt;/scriptgt;
lt;script src=quot;https://cdn.datatables.net/2.3.4/js/dataTables.min.jsquot;gt;lt;/scriptgt;
lt;/codegt;lt;/pregt;
lt;hr /gt;
lt;h2gt;1. Tablelt;/h2gt;
lt;pregt;lt;codegt;lt;table id=quot;postsTablequot; class=quot;min-w-fullquot;gt;
lt;theadgt;
lt;trgt;
lt;thgt;IDlt;/thgt;
lt;thgt;Tiêu đềlt;/thgt;
lt;thgt;Userlt;/thgt;
lt;thgt;Ngày đănglt;/thgt;
lt;/trgt;
lt;/theadgt;
lt;tbodygt;
@foreach($posts as $post)
lt;trgt;
lt;tdgt;{{ $post-gt;id }}lt;/tdgt;
lt;tdgt;{{ $post-gt;title }}lt;/tdgt;
lt;tdgt;{{ $post-gt;user-gt;name }}lt;/tdgt;
lt;tdgt;{{ $post-gt;created_at-gt;format(#39;d/m/Y#39;) }}lt;/tdgt;
lt;/trgt;
@endforeach
lt;/tbodygt;
lt;/tablegt;
lt;/codegt;lt;/pregt;
lt;hr /gt;
lt;h2gt;2. Khởi tạolt;/h2gt;
lt;pregt;lt;codegt;new DataTable(#39;#postsTable#39;, {
pageLength: 10,
responsive: true,
ordering: true,
searching: true,
info: true,
lengthChange: true
});
lt;/codegt;lt;/pregt;
lt;pgt;Là có ngaylt;/pgt;
lt;ulgt;
lt;ligt;Searchlt;/ligt;
lt;ligt;Sortlt;/ligt;
lt;ligt;Paginationlt;/ligt;
lt;/ulgt;
lt;hr /gt;
lt;h2gt;3. Việt hóalt;/h2gt;
lt;pregt;lt;codegt;new DataTable(#39;#postsTable#39;, {
language: {
search: quot;🔍 Tìm kiếm:quot;,
lengthMenu: quot;Hiển thị _MENU_ dòngquot;,
info: quot;Hiển thị _START_ đến _END_ / _TOTAL_quot;,
paginate: {
first: quot;Đầuquot;,
last: quot;Cuốiquot;,
next: quot;Sauquot;,
previous: quot;Trướcquot;
},
zeroRecords: quot;Không tìm thấy dữ liệuquot;,
emptyTable: quot;Chưa có dữ liệuquot;
}
});
lt;/codegt;lt;/pregt;
lt;hr /gt;
lt;h2gt;4. Lúc này Controller chỉ cầnlt;/h2gt;
lt;pregt;lt;codegt;public function index()
{
$posts = Post::with(#39;user#39;)
-gt;latest()
-gt;get();
return view(#39;posts.index#39;, compact(#39;posts#39;));
}
lt;/codegt;lt;/pregt;
lt;pgt;Không cần code search nữa vì DataTables search ngay trên trình duyệt.lt;/pgt;
lt;hr /gt;
lt;h2gt;5. Sau này nâng cấplt;/h2gt;
lt;pgt;Khi số lượng bài viết lớn (ví dụ lt;stronggt;10.000–100.000 bàilt;/stronggt;), không nên tải tất cả về trình duyệt. Khi đó nên dùng lt;stronggt;Server-side Processinglt;/stronggt; của DataTables:lt;/pgt;
lt;pregt;lt;codegt;return DataTables::eloquent(
Post::with(#39;user#39;)
)-gt;toJson();
lt;/codegt;lt;/pregt;
lt;pgt;Kết hợp với gói lt;stronggt;Yajra DataTableslt;/stronggt; trong Laravel để:lt;/pgt;
lt;ulgt;
lt;ligt;Search ở database.lt;/ligt;
lt;ligt;Sort ở database.lt;/ligt;
lt;ligt;Pagination ở database.lt;/ligt;
lt;ligt;Tốc độ rất nhanh dù có hàng trăm nghìn bản ghi.lt;/ligt;
lt;/ulgt;
lt;pgt;Mục 4 nên hiển thị all posts cho admin only...lt;/pgt;lt;pgt;Trong Laravel nên xử lý ở lt;stronggt;Controllerlt;/stronggt; bằng cách kiểm tra role/admin trước khi query.lt;/pgt;lt;pgt;Ví dụ bạn đang có cột lt;code inline=quot;quot;gt;rolelt;/codegt; trong bảng lt;code inline=quot;quot;gt;userslt;/codegt; (lt;code inline=quot;quot;gt;adminlt;/codegt;, lt;code inline=quot;quot;gt;editorlt;/codegt;, lt;code inline=quot;quot;gt;userlt;/codegt;) như các bài trước, có thể làm:lt;/pgt;lt;pregt;lt;code class=quot;language-phpquot;gt;use Illuminate\Support\Facades\Auth;
public function index()
{
$user = Auth::user();
if ($user-gt;isAdmin()) {
// Admin xem tất cả bài viết
$posts = Post::with(#39;user#39;)
-gt;latest()
-gt;get();
} else {
// User thường chỉ xem bài của mình
$posts = Post::with(#39;user#39;)
-gt;where(#39;user_id#39;, $user-gt;id)
-gt;latest()
-gt;get();
}
return view(#39;posts.index#39;, compact(#39;posts#39;));
}
lt;/codegt;lt;/pregt;lt;hr /gt;lt;pgt;Sau đó thêm function lt;code inline=quot;quot;gt;isAdmin()lt;/codegt; trong lt;stronggt;User Modellt;/stronggt;:lt;/pgt;lt;pgt;lt;code inline=quot;quot;gt;app/Models/User.phplt;/codegt;lt;/pgt;lt;pregt;lt;code class=quot;language-phpquot;gt;public function isAdmin()
{
return strtolower($this-gt;role) === #39;admin#39;;
}
lt;/codegt;lt;/pregt;lt;hr /gt;lt;pgt;Khi đó logic sẽ là:lt;/pgt;lt;tablegt;lt;theadgt;lt;trgt;lt;thgt;Userlt;/thgt;lt;thgt;Querylt;/thgt;lt;/trgt;lt;/theadgt;lt;tbodygt;lt;trgt;lt;tdgt;Adminlt;/tdgt;lt;tdgt;lt;code inline=quot;quot;gt;Post::all()lt;/codegt; → thấy tất cả postslt;/tdgt;lt;/trgt;lt;trgt;lt;tdgt;Userlt;/tdgt;lt;tdgt;lt;code inline=quot;quot;gt;where(#39;user_id#39;, Auth::id())lt;/codegt; → chỉ thấy posts của mìnhlt;/tdgt;lt;/trgt;lt;/tbodygt;lt;/tablegt;lt;hr /gt;lt;pgt;Có thể viết gọn hơn bằng toán tử 3 ngôi:lt;/pgt;lt;pregt;lt;code class=quot;language-phpquot;gt;public function index()
{
$user = Auth::user();
$posts = Post::with(#39;user#39;)
-gt;when(!$user-gt;isAdmin(), function ($query) use ($user) {
$query-gt;where(#39;user_id#39;, $user-gt;id);
})
-gt;latest()
-gt;get();
return view(#39;posts.index#39;, compact(#39;posts#39;));
}
lt;/codegt;lt;/pregt;lt;pgt;Cách này Laravel style hơn vì chỉ có lt;stronggt;một query chainlt;/stronggt;.lt;/pgt;lt;pgt;Sau này mở rộng thêm:lt;/pgt;lt;ulgt;lt;ligt;lt;pgt;Admin → CRUD tất cảlt;/pgt;lt;/ligt;lt;ligt;lt;pgt;Editor → sửa bài được giaolt;/pgt;lt;/ligt;lt;ligt;lt;pgt;User → chỉ CRUD bài của mìnhlt;/pgt;lt;/ligt;lt;/ulgt;lt;pgt;thì nên chuyển sang lt;stronggt;Laravel Policy + Gatelt;/stronggt; thay vì kiểm tra trực tiếp trong Controller.lt;/pgt;lt;pgt;x1lt;/pgt;lt;divgt;quay về lt;a href=quot;http://www.lophocvitinh.com/2026/07/laravel-13-2026-tu-php-core-en-full.htmlquot; target=quot;_blankquot;gt;MỤC LỤClt;/agt;lt;/divgt;