Laravel AT Protocol Client (alpha & unstable)
at dev 2.6 kB view raw
1<?php 2 3namespace SocialDept\AtpClient\Auth; 4 5use Illuminate\Support\Facades\Http; 6use SocialDept\AtpClient\Data\AccessToken; 7use SocialDept\AtpClient\Data\DPoPKey; 8use SocialDept\AtpClient\Enums\AuthType; 9use SocialDept\AtpClient\Exceptions\AuthenticationException; 10use SocialDept\AtpClient\Http\DPoPClient; 11 12class TokenRefresher 13{ 14 public function __construct( 15 protected DPoPClient $dpopClient, 16 protected ClientAssertionManager $clientAssertion, 17 ) {} 18 19 /** 20 * Refresh access token using refresh token. 21 * NOTE: Refresh tokens are single-use! 22 */ 23 public function refresh( 24 string $refreshToken, 25 string $pdsEndpoint, 26 DPoPKey $dpopKey, 27 ?string $handle = null, 28 AuthType $authType = AuthType::OAuth, 29 ): AccessToken { 30 return $authType === AuthType::Legacy 31 ? $this->refreshLegacy($refreshToken, $pdsEndpoint, $handle) 32 : $this->refreshOAuth($refreshToken, $pdsEndpoint, $dpopKey, $handle); 33 } 34 35 /** 36 * Refresh OAuth session using /oauth/token endpoint with DPoP. 37 */ 38 protected function refreshOAuth( 39 string $refreshToken, 40 string $pdsEndpoint, 41 DPoPKey $dpopKey, 42 ?string $handle, 43 ): AccessToken { 44 $tokenUrl = $pdsEndpoint.'/oauth/token'; 45 46 $response = $this->dpopClient->request($pdsEndpoint, $tokenUrl, 'POST', $dpopKey) 47 ->asForm() 48 ->post($tokenUrl, array_merge( 49 $this->clientAssertion->getAuthParams($pdsEndpoint), 50 [ 51 'grant_type' => 'refresh_token', 52 'refresh_token' => $refreshToken, 53 ] 54 )); 55 56 if ($response->failed()) { 57 throw new AuthenticationException('Token refresh failed: '.$response->body()); 58 } 59 60 return AccessToken::fromResponse($response->json(), $handle, $pdsEndpoint); 61 } 62 63 /** 64 * Refresh legacy session using /xrpc/com.atproto.server.refreshSession endpoint. 65 */ 66 protected function refreshLegacy( 67 string $refreshToken, 68 string $pdsEndpoint, 69 ?string $handle, 70 ): AccessToken { 71 $response = Http::withHeader('Authorization', 'Bearer '.$refreshToken) 72 ->withBody('', 'application/json') 73 ->post($pdsEndpoint.'/xrpc/com.atproto.server.refreshSession'); 74 75 if ($response->failed()) { 76 throw new AuthenticationException('Token refresh failed: '.$response->body()); 77 } 78 79 return AccessToken::fromResponse($response->json(), $handle, $pdsEndpoint); 80 } 81}