Rumah > Soal Jawab > teks badan
Jadi saya sedang membangunkan aplikasi pentadbir Laravel yang menggunakan API luaran, mari kita panggil PlatformAPI. Cara platform berfungsi ialah pengguna apl saya mempunyai akaun pada platform. Aplikasi Laravel saya akan bertindak sebagai papan pemuka pentadbir supaya pengguna boleh melihat beberapa laporan asas yang diperoleh daripada PlatformAPI.
Setiap pengguna dalam apl saya mesti menambah ID pelanggan dan rahsia pelanggan mereka, yang boleh mereka cipta dalam platform. Dengan cara ini, aplikasi saya akan dapat melaksanakan permintaan kepada PlatformAPI bagi pihak mereka menggunakan bukti kelayakan pengguna.
Saya telah membaca beberapa artikel dan tutorial yang pada asasnya menerangkan cara menyediakan bukti kelayakan/token untuk perkhidmatan dan mengikat perkhidmatan itu kepada ServiceProvider seperti ini:
<?php namespace AppServicesPlatformAPI; class Client { protected string $clientId; protected string $clientSecret; public function __construct(string $clientId, string $clientSecret) { $this->clientId = $clientId; $this->clientSecret = $clientSecret; } public function getSales(string $month) { // ... } } <?php use AppServicesPlatformApiClient; class PlatformApiServiceProvider extends ServiceProvider { public function register() { $this->app->singleton(Client::class, function ($app) { return new Client( clientId: config('services.platform-api.client-id'), clientSecret: config('services.platform-api.client-secret'), ); }); } }
Dengan cara ini anda tidak perlu menetapkan kelayakan pelanggan setiap kali anda ingin menggunakan PlatformApi, saya boleh menghubungi perkhidmatan seperti ini:
<?php namespace AppHttpControllers; use AppServicesPlatformApiClient; class RandomController extends Controller { protected Client $client; public function __construct(Client $client) { $this->client = $client; } public function index() { $this->client->getSales(string $month); } }
Walau bagaimanapun, memandangkan saya perlu melaksanakan permintaan kepada PlatformApi bagi pihak pengguna apl saya menggunakan bukti kelayakan yang mereka sediakan (dan simpan dalam pangkalan data apl saya), saya tidak pasti sama ada pendekatan yang sama ini akan berfungsi seperti singleton Bolehkah ia hanya boleh dibuat sekali sahaja?
Selain itu, untuk menggunakan PlatformApi, saya perlu mendapatkan token akses menggunakan kelayakan pengguna. Token akses ini juga perlu disimpan di suatu tempat (dalam cache saya rasa).
Saya agak buntu tentang cara membetulkannya. Sebarang petunjuk akan amat dihargai.
P粉5236250802023-12-14 13:41:31
Saya menganggap semua aplikasi anda akan menggunakan perkhidmatan pelanggan ini. Jika ya, anda boleh terus menggunakan corak reka bentuk tunggal (untuk menghentikan permintaan oauth selanjutnya), tetapi cuba pisahkan logik daripada kaedah daftar penyedia. Anda boleh mengembalikan access_token
的私有方法后实例化 Client 类(如果存在有效令牌,则检查 DB
/ Cache
expires_in
时间戳值并返回它,或者向用户请求一个新的client
/secret
yang sah dalam panggilan dan mengembalikannya)
/** * Register any application services. * * @return void */ public function register(): void { $this->app->singleton(Client::class, function () { return new Client( accessToken: $this->getUserToken()->access_token ); }); } /** * Tries to get the user token from the database. * * @return ClientCredentials */ private function getUserToken(): ClientCredentials { $credentials = ClientCredentials::query() ->latest() ->find(id: auth()->user()->id); if ($credentials === null || now() > $credentials->expires_at) { $credentials = $this->requestUserToken(); } return $credentials; } /** * Requests a new token for the user & stores it in the database. * * @return ClientCredentials */ private function requestUserToken(): ClientCredentials { $tokenResponse = API::requestToken( client: auth()->user()->client, secret: auth()->user()->secret, ); return ClientCredentials::query()->create( attributes: [ 'user_id' => auth()->user()->id, 'access_token' => $tokenResponse['access_token'], 'refresh_token' => $tokenResponse['refresh_token'], 'token_type' => 'Bearer', 'expires_at' => new DateTime(datetime: '+' . $tokenResponse['expires_in'] . ' seconds') ], ); }