initial: bootstrap from BukidBountyApp base

This commit is contained in:
Jonathan Sykes
2026-06-06 18:43:00 +08:00
commit eb4a5731fb
5674 changed files with 160857 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
namespace App\Auth;
use App\Models\PersonalAccessToken;
use App\Models\User;
use Hyperf\Context\Context;
use Psr\Http\Message\ServerRequestInterface;
class BearerTokenResolver
{
public const CONTEXT_KEY = '__bearer.access_token';
public static function resolve(ServerRequestInterface $request): ?User
{
$plain = self::extract($request);
if ($plain === null) {
return null;
}
$secret = str_contains($plain, '|') ? explode('|', $plain, 2)[1] : $plain;
$token = PersonalAccessToken::findByPlainToken($secret);
if ($token === null || ! $token->isActive()) {
return null;
}
$user = $token->tokenable()->first();
if (! $user instanceof User || ! $user->active) {
return null;
}
$ip = self::clientIp($request);
$token->forceFill([
'last_used_at' => now(),
'last_used_ip' => $ip,
])->save();
$user->withAccessToken($token);
Context::set(self::CONTEXT_KEY, $token);
return $user;
}
public static function current(): ?PersonalAccessToken
{
$token = Context::get(self::CONTEXT_KEY);
return $token instanceof PersonalAccessToken ? $token : null;
}
private static function extract(ServerRequestInterface $request): ?string
{
$header = $request->getHeaderLine('Authorization');
if ($header !== '' && stripos($header, 'Bearer ') === 0) {
return trim(substr($header, 7));
}
return null;
}
public static function clientIp(ServerRequestInterface $request): string
{
foreach (['X-Forwarded-For', 'X-Real-IP'] as $h) {
$val = $request->getHeaderLine($h);
if ($val !== '') {
return trim(explode(',', $val)[0]);
}
}
$server = $request->getServerParams();
return $server['remote_addr'] ?? $server['REMOTE_ADDR'] ?? '0.0.0.0';
}
}