You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel认证授权自定义:从members表认证、services表授权

嘿,我刚好折腾过类似的需求,给你一步步拆解怎么实现 Laravel 下用自定义表做认证和授权:

一、先搞定基于 members 表的用户认证

Laravel 的认证系统是可扩展的,我们只需要自定义认证模型和配置就能绕开默认的 users 表。

1. 创建 Member 模型

这个模型要实现 Laravel 认证所需的接口,指定对应的表和字段:

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class Member extends Authenticatable
{
    // 指定使用 members 表
    protected $table = 'members';
    
    // 如果你的主键不是默认的 id,而是 Username,就加上这行
    protected $primaryKey = 'Username';
    
    // 允许批量赋值的字段,根据你的表结构调整
    protected $fillable = ['Username', 'Rank', 'Name', 'Password'];

    // 重写密码字段获取方法,因为你的密码字段是 Password(首字母大写)
    public function getAuthPassword()
    {
        return $this->Password;
    }

    // 如果主键是 Username,还需要重写这两个方法
    public function getAuthIdentifierName()
    {
        return 'Username';
    }

    public function getAuthIdentifier()
    {
        return $this->getKey();
    }
}

2. 修改认证配置文件

打开 config/auth.php,调整 guard 和 provider 配置,让系统使用我们的 Member 模型:

return [
    'defaults' => [
        'guard' => 'web',
        'passwords' => 'members', // 这里也改成 members
    ],

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'members', // 把 provider 换成 members
        ],
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        // 添加我们的 members 提供者
        'members' => [
            'driver' => 'eloquent',
            'model' => App\Models\Member::class,
        ],
    ],

    // 别忘了添加密码重置的配置(如果需要的话)
    'passwords' => [
        'members' => [
            'provider' => 'members',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],
    ],
];

3. 自定义登录控制器(可选,也可以改默认的)

如果你不想用默认的 LoginController,就新建一个专门的 MemberLoginController,指定使用我们的 guard:

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Facades\Auth;

class MemberLoginController extends Controller
{
    use AuthenticatesUsers;

    // 登录成功后的跳转路径
    protected $redirectTo = '/dashboard';

    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    // 指定使用 members guard 进行认证
    protected function guard()
    {
        return Auth::guard('members');
    }

    // 重写登录字段,因为我们用的是 Username 而不是默认的 email
    public function username()
    {
        return 'Username';
    }
}

然后在 routes/web.php 里添加登录路由:

Route::get('/member/login', [App\Http\Controllers\Auth\MemberLoginController::class, 'showLoginForm'])->name('member.login');
Route::post('/member/login', [App\Http\Controllers\Auth\MemberLoginController::class, 'login']);
Route::post('/member/logout', [App\Http\Controllers\Auth\MemberLoginController::class, 'logout'])->name('member.logout');
二、基于 services 表的权限授权

接下来处理权限部分,我们可以用 Laravel 的 Gate 或者 Policy 来实现,结合 services 表的数据。

1. 创建 Service 模型并关联 Member

先定义 Service 模型,建立和 Member 的关联:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Service extends Model
{
    protected $table = 'services';
    protected $fillable = ['username', 'user_services'];

    // 关联 Member 模型,外键是 username 对应 members 表的 Username
    public function member()
    {
        return $this->belongsTo(Member::class, 'username', 'Username');
    }
}

然后在 Member 模型里添加反向关联:

// 在 App\Models\Member 里添加
public function services()
{
    return $this->hasMany(Service::class, 'username', 'Username');
}

2. 用 Gate 定义权限规则

打开 app/Providers/AuthServiceProvider.php,在 boot 方法里定义权限检查逻辑:

use App\Models\Member;
use Illuminate\Support\Facades\Gate;

public function boot()
{
    $this->registerPolicies();

    // 定义一个通用的权限检查 Gate:检查用户是否有权限访问某个服务
    Gate::define('access-service', function (Member $member, $serviceName) {
        // 从 services 表查询该用户是否拥有指定服务
        return $member->services()->where('user_services', $serviceName)->exists();
    });
}

3. 在代码中使用权限检查

控制器里检查:

public function payment()
{
    // 检查当前登录用户是否有权限访问 payment 服务
    if (!Gate::allows('access-service', 'payment')) {
        abort(403, '你没有权限访问该服务');
    }

    return view('payment.index');
}

视图里检查:

@can('access-service', 'payment')
    <a href="/payment" class="btn btn-primary">支付服务</a>
@else
    <span class="text-muted">无支付权限</span>
@endcan

4. (可选)自定义权限中间件

如果要在路由层面统一检查权限,可以创建一个中间件:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Gate;

class CheckServiceAccess
{
    public function handle($request, Closure $next, $service)
    {
        if (!Gate::allows('access-service', $service)) {
            abort(403, '无权限访问该服务');
        }

        return $next($request);
    }
}

然后在 app/Http/Kernel.php 里注册这个中间件:

protected $routeMiddleware = [
    // ...其他中间件
    'service.access' => \App\Http\Middleware\CheckServiceAccess::class,
];

之后就可以在路由里直接使用:

Route::get('/payment', [PaymentController::class, 'index'])->middleware('service.access:payment');
注意事项
  • 确保 members 表的 Password 字段存储的是哈希后的密码,注册用户时要用 Hash::make($password) 来加密。
  • 如果你的 members 表主键不是自增 ID(比如 Username 是字符串),要在 Member 模型里加上 public $incrementing = false; 和 protected $keyType = 'string';。
  • 测试时要清空浏览器缓存,避免之前的 session 干扰。

如果某个步骤出现报错,比如认证失败、权限检查不生效,可以贴出具体的错误信息,我再帮你排查~

内容的提问来源于stack exchange,提问作者Hemant Maurya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:25:31