Rumah  >  Soal Jawab  >  teks badan

Cara menggunakan penyedia perkhidmatan Laravel untuk penggunaan API luaran (memanfaatkan kelayakan berasaskan pengguna)

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粉465675962P粉465675962334 hari yang lalu440

membalas semua(1)saya akan balas

  • P粉523625080

    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')
                ],
            );
        }

    balas
    0
  • Batalbalas