Laravel 8.0手动实现管理员与普通用户角色鉴权及路由配置最佳实践
Hey there! I’ve built exactly this kind of system multiple times for Laravel projects, so I can walk you through a straightforward, secure approach that doesn’t rely on any third-party packages. Let’s break it down step by step:
1. Add a Role Field to Your Users Table
First, we need a way to distinguish admins from regular users. Let’s add a role column to the users table:
- Generate a migration:
php artisan make:migration add_role_to_users_table - Open the new migration file and update the
up()method:public function up() { Schema::table('users', function (Blueprint $table) { // Use enum for strict role values (prevents invalid roles) $table->enum('role', ['user', 'admin'])->default('user'); }); } - Run the migration:
php artisan migrate
Add Helper Methods to the User Model
Make it easy to check a user’s role by adding these methods to app/Models/User.php:
public function isAdmin(): bool { return $this->role === 'admin'; } public function isRegularUser(): bool { return $this->role === 'user'; }
2. Manual Authentication Setup (No Breeze/UI Packages)
Since you’re familiar with the old make:auth command, let’s replicate that core functionality manually:
Authentication Routes
Add these routes to routes/web.php:
// Guest-only routes (login/register) Route::middleware('guest')->group(function () { Route::get('/login', [AuthController::class, 'showLoginForm'])->name('login'); Route::post('/login', [AuthController::class, 'login']); Route::get('/register', [AuthController::class, 'showRegistrationForm'])->name('register'); Route::post('/register', [AuthController::class, 'register']); }); // Authenticated user routes Route::middleware('auth')->group(function () { Route::post('/logout', [AuthController::class, 'logout'])->name('logout'); // Regular user dashboard Route::get('/dashboard', [UserController::class, 'dashboard'])->name('user.dashboard'); }); // Admin-only routes (protected by custom middleware) Route::middleware(['auth', 'admin'])->group(function () { Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard'); // Add other admin routes here (e.g., user management, settings) });
Auth Controller
Create an AuthController with the core auth logic. Here’s a simplified version:
namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use App\Models\User; use Illuminate\Support\Facades\Hash; class AuthController extends Controller { public function showLoginForm() { return view('auth.login'); } public function login(Request $request) { $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], ]); if (Auth::attempt($credentials)) { $request->session()->regenerate(); // Redirect based on role return Auth::user()->isAdmin() ? redirect()->intended(route('admin.dashboard')) : redirect()->intended(route('user.dashboard')); } return back()->withErrors([ 'email' => 'The provided credentials do not match our records.', ])->onlyInput('email'); } public function showRegistrationForm() { return view('auth.register'); } public function register(Request $request) { $request->validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'password' => ['required', 'string', 'min:8', 'confirmed'], ]); $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), // Default role is 'user' (set in migration) ]); Auth::login($user); return redirect(route('user.dashboard')); } public function logout(Request $request) { Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect('/'); } }
Basic Auth Views
Create simple Blade views for login/register in resources/views/auth/:
login.blade.php: A form with email/password fields pointing to/loginregister.blade.php: A form with name/email/password/password_confirmation fields pointing to/register
3. Custom Admin Middleware
To protect admin routes, create a middleware that checks if the authenticated user is an admin:
- Generate the middleware:
php artisan make:middleware AdminMiddleware - Open
app/Http/Middleware/AdminMiddleware.phpand update thehandle()method:public function handle(Request $request, Closure $next) { if (!Auth::check() || !Auth::user()->isAdmin()) { // Redirect regular users to their dashboard or show 403 abort(403, 'You are not authorized to access this page.'); } return $next($request); } - Register the middleware in
app/Http/Kernel.phpunder$routeMiddleware:protected $routeMiddleware = [ // ... existing middleware 'admin' => \App\Http\Middleware\AdminMiddleware::class, ];
4. Blade View Role Differentiation
Use Blade’s conditional directives to show/hide content based on the user’s role:
Example: Navigation Bar
In your main layout (resources/views/layouts/app.blade.php):
<nav class="navbar"> <a href="{{ route('home') }}">Home</a> @auth @if(auth()->user()->isAdmin()) <a href="{{ route('admin.dashboard') }}">Admin Dashboard</a> <a href="{{ route('admin.users') }}">Manage Users</a> @else <a href="{{ route('user.dashboard') }}">My Dashboard</a> @endif <form method="POST" action="{{ route('logout') }}" class="logout-form"> @csrf <button type="submit">Logout</button> </form> @endauth @guest <a href="{{ route('login') }}">Login</a> <a href="{{ route('register') }}">Register</a> @endguest </nav>
Example: Dashboard Views
resources/views/user/dashboard.blade.php: Content for regular users (e.g., personal profile, order history)resources/views/admin/dashboard.blade.php: Content for admins (e.g., user stats, system settings)
5. Extra Security Tips
- Double-check roles in controllers: Even with middleware, add a quick check at the start of admin controller methods to be safe:
public function dashboard() { abort_unless(auth()->user()->isAdmin(), 403); return view('admin.dashboard'); } - Restrict role updates: Only let admins change user roles (never let regular users modify their own role via forms/API)
- Use Laravel’s built-in auth features: Leverage things like password reset tokens and session regeneration (we already included session regeneration in the login method)
This setup is lightweight, secure, and fully customizable—no third-party packages required. You can expand it later (e.g., add more roles) by updating the enum and model methods.
内容的提问来源于stack exchange,提问作者Lex

