Laravel多认证:如何用单一登录表单与LoginController实现双角色登录
当然可以!完全能用单个登录表单和控制器实现多角色认证,我来一步步给你拆解怎么做:
1. 给用户表添加角色标识字段
首先得区分用户是客户还是卖家,我们给users表加一个role字段来存储角色类型。先创建迁移文件:
php artisan make:migration add_role_to_users_table --table=users
打开生成的迁移文件,写入以下代码:
public function up() { Schema::table('users', function (Blueprint $table) { // 用枚举类型限定只能是customer或seller,默认给customer $table->enum('role', ['customer', 'seller'])->default('customer'); }); } public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('role'); }); }
运行迁移生效:
php artisan migrate
2. 修改LoginController的登录后逻辑
默认的LoginController继承了AuthenticatesUsers trait,我们只需要重写authenticated方法,就能在用户登录成功后根据角色跳转到不同页面。
打开app/Http/Controllers/Auth/LoginController.php,添加以下方法:
use Illuminate\Http\Request; protected function authenticated(Request $request, $user) { // 根据用户角色跳转对应仪表盘 if ($user->role === 'seller') { return redirect()->route('seller.dashboard'); } // 默认跳转到客户仪表盘 return redirect()->route('customer.dashboard'); }
注:如果需要在登录时就验证角色(比如限制某些角色登录特定后台),也可以重写
attemptLogin方法,但一般更推荐登录后用中间件控制权限,更灵活。
3. 配置角色权限中间件
为了防止不同角色越权访问页面,我们需要一个中间件来验证用户角色。先创建中间件:
php artisan make:middleware CheckRole
打开app/Http/Middleware/CheckRole.php,编写验证逻辑:
use Closure; use Illuminate\Http\Request; public function handle(Request $request, Closure $next, ...$roles) { // 检查当前登录用户的角色是否在允许的角色列表里 if (!in_array(auth()->user()->role, $roles)) { abort(403, '你没有权限访问该页面'); } return $next($request); }
把这个中间件注册到app/Http/Kernel.php的$routeMiddleware数组中:
protected $routeMiddleware = [ // ...其他默认中间件 'role' => \App\Http\Middleware\CheckRole::class, ];
4. 配置角色专属路由
在routes/web.php里,用中间件分组来定义不同角色能访问的路由:
// 公共路由(首页、登录注册等) Route::get('/', function () { return view('welcome'); }); // 默认的Auth路由(包含登录、注册、退出等) Auth::routes(); // 客户专属路由组:必须登录且角色为customer才能访问 Route::middleware(['auth', 'role:customer'])->group(function () { Route::get('/customer/dashboard', [CustomerController::class, 'dashboard'])->name('customer.dashboard'); // 这里添加其他客户相关的路由 }); // 卖家专属路由组:必须登录且角色为seller才能访问 Route::middleware(['auth', 'role:seller'])->group(function () { Route::get('/seller/dashboard', [SellerController::class, 'dashboard'])->name('seller.dashboard'); // 这里添加其他卖家相关的路由 });
5. 登录表单无需修改
你完全可以保留默认的登录表单(resources/views/auth/login.blade.php),只需要用户输入邮箱和密码即可——角色信息是从数据库读取的,不需要用户在登录时选择。
(可选)注册时让用户选择角色
如果需要用户注册时自行选择角色,可以修改注册表单和控制器:
- 修改
resources/views/auth/register.blade.php,添加角色选择框:
<div class="form-group row"> <label for="role" class="col-md-4 col-form-label text-md-right">{{ __('角色') }}</label> <div class="col-md-6"> <select id="role" class="form-control @error('role') is-invalid @enderror" name="role" required> <option value="customer">客户</option> <option value="seller">卖家</option> </select> @error('role') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div>
- 修改
RegisterController的验证和创建逻辑:
// 验证规则里添加role的校验 protected function validator(array $data) { return Validator::make($data, [ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'password' => ['required', 'string', 'min:8', 'confirmed'], 'role' => ['required', 'string', 'in:customer,seller'], ]); } // 创建用户时存储角色信息 protected function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), 'role' => $data['role'], ]); }
这样就搞定了!用户用同一个登录表单登录后,系统会自动根据角色跳转到对应的页面,而且中间件会严格限制不同角色的访问权限。
内容的提问来源于stack exchange,提问作者andri purnama

