多个防护的user_id冲突laravel

a2mppw5e  于 2023-01-31  发布在  其他
关注(0)|答案(3)|浏览(173)

我是新来的Laravel,我创建了两个警卫“用户警卫”(默认一个)和“管理员警卫”。我保存在数据库而不是文件认证会话。
现在的问题是用户ID在会话表中引起冲突。例如,如果我在用户表中创建一个新用户,在管理表中创建一个新管理员帐户,两者在会话表中将具有相同的ID,并且由于ID不是唯一的,它会自动将我登录到管理员帐户,即使我只是以普通用户身份登录。
我已经在谷歌上搜索过了,但没有找到任何有用的东西。只有这个家伙问了同样的问题,但没有工作的答案:Multi session tables in Laravel
下面是我的代码:config/auth.php

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'token',
        'provider' => 'users',
        'hash' => false,
    ],
    'admin' => [
        'driver' => 'session',
        'provider' => 'admins',

    ],
],

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\User::class,
    ],
    'admins' => [
        'driver' => 'eloquent',
        'model' => App\Admin::class,

    ]
],

AdminLoginController.php

if (auth()->guard('admin')->attempt(['email' => $request->email, 'password' => $request->password])) {
    $user = auth()->guard('admin')->user();
    return redirect()->route('admin');

}
ie3xauqp

ie3xauqp1#

可能不应该有一个单独的表格和单独的雄辩模型的管理员,因为一个管理员 * 是 * 一个用户。他们只是一个用户与提升权限。
考虑将角色和/或权限附加到用户模型以跟踪用户是否为管理员,而不是为管理员创建单独的模型、保护和提供程序。
这里有一个很好的包来帮助:https://github.com/spatie/laravel-permission

jhdbpxl9

jhdbpxl92#

我不确定这是否矛盾。我相信你只是没有正确使用警卫。
你需要确保,如果你以Admin的身份登录,你从来没有调用Auth::user()。你应该总是需要使用Auth::guard('admin')->user()

mf98qq94

mf98qq943#

扩展laravel默认值DatabaseSessionHandler并覆盖addUserInformation函数

<?php

namespace App\Extensions;

use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Session\DatabaseSessionHandler;

class CustomDatabaseSessionHandler extends DatabaseSessionHandler
{
    /**
     * Add the user information to the session payload.
     *
     * @param array $payload
     * @return $this
     * @throws BindingResolutionException
     */
    protected function addUserInformation(&$payload): static
    {
        if ($this->container->bound(Guard::class)) {
            info(($this->user() ? get_class($this->user()) : null));
            $payload['userable_type'] = $this->user() ? get_class($this->user()) : null;
            $payload['userable_id'] = $this->userId();
        }

        return $this;
    }

    /**
     * Get the currently authenticated user's ID.
     *
     * @return mixed
     * @throws BindingResolutionException
     */
    protected function user(): mixed
    {
        return $this->container->make(Guard::class)->user();
    }
}

然后在AppServiceProvider中注册驱动程序

public function boot(): void
    {
        Session::extend('custom-database', function ($app) {
            $table = $app['config']['session.table'];
            $lifetime = $app['config']['session.lifetime'];
            $connection = $app['db']->connection($app['config']['session.connection']);

            return new CustomDatabaseSessionHandler($connection, $table, $lifetime, $app);
        });
    }

更改会话表迁移

public function up()
    {
        Schema::create('sessions', function (Blueprint $table) {
            $table->string('id')->primary();
            $table->string('userable_type')->nullable();
            $table->foreignId('userable_id')->nullable()->index();
            $table->string('ip_address', 45)->nullable();
            $table->text('user_agent')->nullable();
            $table->longText('payload');
            $table->integer('last_activity')->index();
        });
    }

然后更改.env文件中的会话驱动程序

SESSION_DRIVER=custom-database

现在,存储在数据库中的会话是多态的

相关问题