首页 > 解决方案 > 使用 Tymon 的 Laravel jwt-auth 对特定守卫的令牌进行身份验证

问题描述

我的 jwt.auth 配置有问题,我需要有关如何让 jwt.auth 使用我的租户用户保护的帮助。

目前,我可以登录并正确返回租户警卫上正确模型的令牌。我用它来生成令牌

if ( ! $token = Auth::guard('tenants')->attempt($credentials)) {
         return response()->json(['error' => 'invalid credentials'], 401);
    }

但是,即使令牌在 24 小时内没有过期,对受保护 API 的后续调用也会使用 401 进行身份验证失败。我想我已经把它缩小到 jwt.auth 试图针对“用户”提供者验证令牌。通过将“App\Models\Tenant\Staff::class”复制到“providers users 模型”来证明这一点。但我想为我的 web 和 api 用户保留(inc 默认值应该是 web)。这是身份验证配置:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'tenants' => [
        'driver' => 'jwt',
        'provider' => 'tenant-users',
    ], 
], 

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\User::class,
    ],
    'tenant-users' => [
        'driver' => 'eloquent',
        'model' => App\Models\Tenant\Staff::class,
    ],
],

是否有任何地方可以设置 jwt.auth 以使用租户保护/租户用户提供程序进行后续 API 调用?我已经搜索过,但还没有结果。我一定是做错了什么。

路线受到如下保护。identifyTenant 只是将数据库连接设置为租户模型的存储位置:

Route::group(['middleware' => ['identifyTenant', 'jwt.auth']], function () {...}

为了完整起见,Staff 模型扩展了 Authenticatable,实现了 JWTSubject。它与“租户”有一个受保护的数据库连接。它实现了函数 getJWTIdentifier 和 getJWTCustomClaims

这是设置租户数据库的代码。我在服务提供商中运行它。

 public function register()
{

    $manager = new TenantManager;

    $this->app->instance(TenantManager::class, $manager);
    $this->app->bind(Tenant::class, function () use ($manager) {
        return $manager->getTenant();
    });
   
    $this->app['db']->extend('tenant', function ($config, $name) use ($manager) {

        $tenant = $manager->getTenant();
      //  dd($tenant);
        if ($tenant) {
            $config['database'] = $tenant->db;
        } 
        return $this->app['db.factory']->make($config, $name);
    });
}

识别租户

public function handle($request, Closure $next)
{
    $domain = parse_url($request->headers->get('origin') , PHP_URL_HOST); //eg http://test.carebase.local

    $pos = strpos($domain, env('TENANT_DOMAIN'));
    $subDomain = substr($domain, 0, $pos-1  );

    if ($pos !== false && $this->tenantManager->loadTenant($subDomain, $domain)) {
        return $next($request);
    }  else {
         Log::warning('CB : unknown tenant tried to access. Host:'.' '.$domain);
        return Abort(403);
    }

}

租户经理

 public function setTenant(?Tenant $tenant, $domain = '') {
    $this->tenant = $tenant;
    $this->tenant->domain = $domain;

    return $this;
}

public function getTenant(): ?Tenant {

    return $this->tenant;
}

public function loadTenant($identifier, $domain): bool {
    // Identify the tenant here
    $tenant = Tenant::query()->where('subdomain', '=', $identifier)->first();

    if ($tenant) {
        //we need domain because we want to track where tenant is calling from. inc scheme.
        $this->setTenant($tenant, $domain);
        return true;
    }
    return false;
}

标签: laraveljwt

解决方案


推荐阅读