Comment utiliser le fournisseur de services de Laravel pour l'utilisation d'API externes (en tirant parti des informations d'identification basées sur l'utilisateur)
P粉465675962
P粉465675962 2023-12-13 21:03:48
0
1
376

Je développe donc une application d'administration Laravel qui utilise une API externe, appelons-la PlatformAPI. Le fonctionnement de la plateforme est que les utilisateurs de mon application disposent d'un compte sur la plateforme. Mon application Laravel agira comme un tableau de bord d'administration afin que les utilisateurs puissent afficher certains rapports de base obtenus à partir de PlatformAPI.

Chaque utilisateur de mon application doit ajouter son identifiant client et son secret client, qu'il peut créer dans la plateforme. De cette façon, mon application pourra effectuer des requêtes auprès de PlatformAPI en leur nom en utilisant les informations d'identification de l'utilisateur.

J'ai lu des articles et des tutoriels qui décrivent essentiellement comment configurer des informations d'identification/jetons pour un service et lier ce service à un fournisseur de services comme ceci :

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

De cette façon, vous n'avez pas besoin de définir les informations d'identification du client à chaque fois que vous souhaitez utiliser PlatformApi, je peux simplement appeler le service comme ceci :

<?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);
    }
}

Cependant, comme je dois effectuer des requêtes auprès de PlatformApi au nom de l'utilisateur de mon application en utilisant les informations d'identification qu'il fournit (et les stocker dans la base de données de mon application), je ne sais pas si cette même approche fonctionnera comme le singleton. être instancié une seule fois ?

De plus, pour utiliser PlatformApi, je dois obtenir un jeton d'accès en utilisant les informations d'identification de l'utilisateur. Ce jeton d'accès doit également être stocké quelque part (dans le cache je suppose).

Je ne sais pas trop comment résoudre ce problème. Tous les indicateurs seraient grandement appréciés.

P粉465675962
P粉465675962

répondre à tous(1)
P粉523625080

Je suppose que toutes vos applications utiliseront ce service client. Si tel est le cas, vous pouvez continuer à utiliser le modèle de conception singleton (pour arrêter d'autres requêtes oauth), mais essayez de séparer la logique de la méthode d'enregistrement du fournisseur. Vous pouvez retourner un access_token 的私有方法后实例化 Client 类(如果存在有效令牌,则检查 DB / Cache expires_in 时间戳值并返回它,或者向用户请求一个新的client/secret valide dans l'appel et le retourner)

/**
     * 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')
            ],
        );
    }
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!