如何将会话变量引入此 Laravel 8 应用程序中的 AuthServiceProvider?

How can I bring a session variable into the AuthServiceProvider in this Laravel 8 application?

我正在开发具有用户、角色和权限的 Laravel 8 应用程序。我使用 Microsoft Azure 进行用户注册和登录。我首先在他们的网站上关注 this tutorial

我在 routes\web.php 中使用自定义中间件来区分经过身份验证的用户和来宾:

Route::group(['prefix' => 'dashboard', 'middleware' => ['checkSignedIn']], function() {
    Route::get('/', [DashboardContoller::class, 'index'])->name('dashboard');
    //More routes
}); 

我从 permissions MySQL table 中获得了每个用户角色特定的 逗号分隔的用户权限列表

我将 userPermissions 变量存储在这样的会话中:

public function storeTokens($accessToken, $user, $user_role, $user_permissions) {
 session([
  'accessToken' => $accessToken->getToken(),
  'refreshToken' => $accessToken->getRefreshToken(),
  'tokenExpires' => $accessToken->getExpires(),
  'userName' => $user->getDisplayName(),
  'firstName' => $user->getGivenName(),
  'lastName' => $user->getSurname(),
  'userRole' => $user_role,
  'userPermissions' => $user_permissions,
  'userEmail' => null !== $user->getMail() ? $user->getMail() : $user->getUserPrincipalName(),
  'userTimeZone' => $user->getMailboxSettings()->getTimeZone()
 ]);
}

这允许我在视图(navbar.blade.php 部分)中直接 输出当前(已登录)用户的 权限列表 会话,像这样:

@if(session('userPermissions'))
  <ul>
    @foreach (session('userPermissions') as $up)
      <li>{{ $up }}</li>
    @endforeach
  </ul>
@endif 

目标

我的本意(创建session('userPermissions')的目的)是在Gates中使用用户的权限。为此,在 app\Providers\AuthServiceProvider.php 我有:

// More code
use Illuminate\Support\Facades\Gate;
// More code

/* View Users */
Gate::define('view-users', function() {
  return in_array('view-users', session('userPermissions'));
});

在基本控制器(app\Http\Controllers\Controller.php)中,我使用 use Illuminate\Support\Facades\Gate 导入了 Gate facade,然后在 users.blade.php

@can('view-users') 
    <h2>Users</h2>
    <table class="table">
        <thead>
            <tr>
                <th>Name</th>
                <th>Email</th>
                <th>Role</th>
            </tr>
        </thead>
        @if ($users)
        <tbody>
            @foreach ($users as $user)
            <tr>
                <td>{{ $user->first_name }} {{ $user->last_name }}</td>
                <td>{{ $user->email }}</td>
                <td>{{ $user->role }}</td>
            </tr>
            @endforeach
        </tbody>
        @endif
    </table>
@endcan 

问题

Evan 如果当前用户确实具有 view-users 权限(并且在导航栏中可见),则用户 table 不存在并且正在执行 dd(session('userPermissions'))AuthServiceProvider.php returns null.

我的错误在哪里?

假设您在 App\Providers\AuthServiceProvider.

中注册了 Policy & Gate
class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        User::class => UserPolicy::class,
    ];
 
    /**
     * Register any application authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        // this merely maps the name of the gate
        Gate::define('view-users', [UserPolicy::class, 'index']);
    }
}

CLI 命令:

php artisan make:policy UserPolicy --model=User

然后在class UserPolicy中,你必须实现方法index()


甚至可以在渲染任何 Blade 模板之前检查控制器。

对于您的用例...请参阅以下示例:Methods Without Models or Guest Users

Gate 知道 User $user ...

时,依赖 session() 毫无意义