Skip to content

CakeDC/cakephp-supabase

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CakePHP Supabase Plugin

License

A CakePHP 5 plugin for integrating with Supabase. This plugin provides a lightweight, custom API client to interact with Supabase services (Auth, Storage, Functions) and a flexible JWT authenticator, without relying on any external, unmaintained Supabase SDKs.

Core Philosophy: This plugin uses CakePHP's built-in Cake\Http\Client for all API interactions, ensuring long-term maintainability and stability. It assumes your main application connects directly to the Supabase PostgreSQL database via the standard CakePHP datasource configuration.


1. Installation

  1. Install via Composer:

    composer require cakedc/supabase
  2. Load the Plugin: In your src/Application.php, load the plugin in the bootstrap() method:

    public function bootstrap(): void
    {
        parent::bootstrap();
    
        // Load the Supabase plugin
        $this->addPlugin('CakeDC/Supabase');
    }

2. Configuration

Database Connection

This plugin does not manage your database connection. You should configure your primary datasource in config/app.php to connect directly to your Supabase PostgreSQL database, just as you would with any other PostgreSQL database.

Plugin Configuration

  1. Copy the Configuration File: Copy the plugin's configuration file from plugins/cakedc/supabase/config/supabase.php to your application's main config directory: config/supabase.php.

  2. Set Environment Variables: Customize config/supabase.php and provide your Supabase credentials, preferably using environment variables.

    Your config/supabase.php should look like this:

    <?php
    return [
        'Supabase' => [
            // Your Supabase project URL.
            'url' => env('SUPABASE_URL', null),
    
            // The service_role key. This key has admin privileges and should be kept secret.
            'serviceRoleKey' => env('SUPABASE_SERVICE_ROLE_KEY', null),
    
            // The JWT secret used to verify the signature of user tokens.
            'jwtSecret' => env('SUPABASE_JWT_SECRET', null),
        ],
    ];

    These settings will be loaded automatically by the plugin's bootstrap.php.


3. Usage

Authentication

This plugin provides a SupabaseJwtAuthenticator to validate Supabase JWTs and identify users in your local database.

  1. Load the Authentication Component: In your src/Application.php, load the Authentication component.

  2. Configure the Authenticator: In your getAuthenticationService method, configure the SupabaseJwtAuthenticator. It is highly flexible and can be configured to use your specific user model and finder.

    // in src/Application.php
    use Authentication\AuthenticationService;
    use Authentication\AuthenticationServiceInterface;
    use Authentication\Identifier\IdentifierInterface;
    use Psr\Http\Message\ServerRequestInterface;
    
    public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
    {
        $service = new AuthenticationService();
    
        // Load identifiers
        $service->loadIdentifier('Authentication.Token', [
            'dataField' => 'sub', // The JWT's sub claim contains the user UUID
            'resolver' => [
                'className' => 'Authentication.Orm',
                'userModel' => 'Users', // Your user model
                'finder' => 'byUuid', // A custom finder on your UsersTable
            ],
        ]);
    
        // Load authenticators
        $service->loadAuthenticator('Authentication.Jwt');
        $service->loadAuthenticator('CakeDC/Supabase.SupabaseJwt', [
            'userModel' => 'Users',
        ]);
    
        return $service;
    }

    Note: For the above example to work, you would need a custom finder findbyUuid in your UsersTable.php.

Service Layer

The SupabaseService acts as a factory for interacting with the Supabase admin APIs. For best practice, you should use CakePHP's dependency injection container to get an instance of the service.

Example: Using the Service in a Controller

Here is an example of how to inject and use the SupabaseService in a controller to fetch a user's admin-level data from Supabase.

Add the following code to Application.php

    public function services(ContainerInterface $container): void
    {
        $container->add(SupabaseService::class);
    }

Then, add the service to the action:

// in src/Controller/UsersController.php
namespace App\Controller;

use CakeDC\Supabase\Service\SupabaseService;

class UsersController extends AppController
{

    /**
     * Get a user's full Supabase profile.
     * This requires admin privileges.
     */
    public function viewProfile(SupabaseService $supabaseService, string $userId)
    {
        $this->request->allowMethod(['get']);

        // The user ID from the route, e.g., a UUID
        $identity = $this->Authentication->getIdentity();
        $loggedInUserId = $identity->get('id');

        try {
            // Use the custom-built AuthAdmin client via the service
            $supabaseUserData = $supabaseService->authAdmin()->getUserById($loggedInUserId);
            $this->set([
                'success' => true,
                'data' => $supabaseUserData,
            ]);
        } catch (\CakeDC\Supabase\Exception\SupabaseApiException $e) {
            $this->set([
                'success' => false,
                'message' => 'Failed to fetch user profile: ' . $e->getMessage(),
            ]);
            $this->response = $this->response->withStatus(500);
        }

        $this->viewBuilder()->setOption('serialize', ['success', 'data', 'message']);
    }
}

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages