mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 11:14:04 +00:00
Fix cookie identification (#56)
* route cloning: Trim '/' from original route prefixes * Decrypt cookie if encrypted in request data ID MW * Fix code style (php-cs-fixer) * Fix PHPStan error [ci skip] * Revert "route cloning: Trim '/' from original route prefixes" This reverts commit 3dc97eba1b3b91b3446bc16fd107385fe835621e. * Fix code style (php-cs-fixer) * add a setting for requiring cookie encryption * Fix code style (php-cs-fixer) --------- Co-authored-by: PHP CS Fixer <phpcsfixer@example.com> Co-authored-by: Samuel Štancl <samuel@archte.ch>
This commit is contained in:
parent
0f7cd2e868
commit
15d12e22c7
1 changed files with 49 additions and 2 deletions
|
|
@ -5,7 +5,9 @@ declare(strict_types=1);
|
|||
namespace Stancl\Tenancy\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Cookie\CookieValuePrefix;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Stancl\Tenancy\Concerns\UsableWithEarlyIdentification;
|
||||
use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedByRequestDataException;
|
||||
use Stancl\Tenancy\Overrides\TenancyUrlGenerator;
|
||||
|
|
@ -21,6 +23,8 @@ class InitializeTenancyByRequestData extends IdentificationMiddleware
|
|||
public static string $queryParameter = 'tenant';
|
||||
public static ?Closure $onFail = null;
|
||||
|
||||
public static bool $requireCookieEncryption = false;
|
||||
|
||||
public function __construct(
|
||||
protected Tenancy $tenancy,
|
||||
protected RequestDataTenantResolver $resolver,
|
||||
|
|
@ -38,7 +42,11 @@ class InitializeTenancyByRequestData extends IdentificationMiddleware
|
|||
TenancyUrlGenerator::$prefixRouteNames = false;
|
||||
|
||||
if ($request->method() !== 'OPTIONS') {
|
||||
return $this->initializeTenancy($request, $next, $this->getPayload($request));
|
||||
return $this->initializeTenancy(
|
||||
$request,
|
||||
$next,
|
||||
$this->getPayload($request)
|
||||
);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
|
@ -48,10 +56,17 @@ class InitializeTenancyByRequestData extends IdentificationMiddleware
|
|||
{
|
||||
if (static::$header && $request->hasHeader(static::$header)) {
|
||||
$payload = $request->header(static::$header);
|
||||
} elseif (static::$queryParameter && $request->has(static::$queryParameter)) {
|
||||
} elseif (
|
||||
static::$queryParameter &&
|
||||
$request->has(static::$queryParameter)
|
||||
) {
|
||||
$payload = $request->get(static::$queryParameter);
|
||||
} elseif (static::$cookie && $request->hasCookie(static::$cookie)) {
|
||||
$payload = $request->cookie(static::$cookie);
|
||||
|
||||
if ($payload) {
|
||||
$payload = $this->getTenantFromCookie($payload);
|
||||
}
|
||||
} else {
|
||||
$payload = null;
|
||||
}
|
||||
|
|
@ -70,4 +85,36 @@ class InitializeTenancyByRequestData extends IdentificationMiddleware
|
|||
{
|
||||
return (bool) $this->getPayload($request);
|
||||
}
|
||||
|
||||
protected function getTenantFromCookie(string $cookie): string|null
|
||||
{
|
||||
// If the cookie looks like it's encrypted, we try decrypting it
|
||||
if (str_starts_with($cookie, 'eyJpdiI')) {
|
||||
try {
|
||||
$json = base64_decode($cookie);
|
||||
$data = json_decode($json, true);
|
||||
|
||||
if (
|
||||
is_array($data) &&
|
||||
isset($data['iv']) &&
|
||||
isset($data['value']) &&
|
||||
isset($data['mac'])
|
||||
) {
|
||||
// We can confidently assert that the cookie is encrypted. If this call were to fail, this method would just
|
||||
// return null and the cookie payload would get skipped.
|
||||
$cookie = CookieValuePrefix::validate(
|
||||
static::$cookie,
|
||||
Crypt::decryptString($cookie),
|
||||
Crypt::getAllKeys()
|
||||
);
|
||||
}
|
||||
} catch (\Throwable) {
|
||||
// In case of any exceptions, we just use the original cookie value.
|
||||
}
|
||||
} elseif (static::$requireCookieEncryption) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $cookie;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue