digram/bukua-auth

Login with Bukua OAuth for your Laravel application

Installs: 80

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 1

Forks: 0

Open Issues: 0

pkg:composer/digram/bukua-auth

v2.1.20 2025-10-01 19:08 UTC

README

This package provides seamless OAuth 2.0 authentication with Bukua for Laravel applications, handling the complete authentication flow and user management.

Table of Contents

Prerequisites

Before using this package, ensure you have:

  1. Bukua Developer Account

  2. Application Credentials

    • Obtain your client_id, client_secret and app_url from the Bukua Developer Dashboard
  3. Laravel Application

    • Laravel 8.x or higher
    • Composer for dependency management

Installation

  1. Install the package via Composer:

    composer require digram/bukua-auth
  2. Clear configuration cache:

    # For development
    php artisan config:clear && php artisan route:clear
    
    # For production
    php artisan config:cache && php artisan route:cache

Configuration

Environment Variables

Add the following variables to your .env file:

# Bukua OAuth Configuration
BUKUA_USER_ACCESS_CLIENT_ID=your-client-id-here
BUKUA_USER_ACCESS_CLIENT_SECRET=your-client-secret-here
BUKUA_USER_ACCESS_APP_URL="https://your-app-url.com"
BUKUA_BASE_URL="https://bukua-core.apptempest.com"  # Development
# BUKUA_BASE_URL="https://app.bukuaplatform.com"    # Production

# Application Settings
BUKUA_USER_MODEL="App\\Models\\User"
BUKUA_REDIRECT_AFTER_LOGIN="/dashboard" # Your authenticated user dashboard URL

Configuration Notes:

  • Environment: Use the development base URL for testing and production URL for live applications
  • User Access App URL: Must exactly match the App URL from your Bukua Developer Dashboard
  • User Model: Ensure this matches your application's User model namespace

Database Setup

  1. Update your User migration:

    Schema::table('users', function ($table) {
        $table->char('bukua_user_id', 36)->nullable()->index();
        $table->text('bukua_access_token')->nullable();
        $table->text('bukua_refresh_token')->nullable();
        $table->string('name')->nullable();
        // Consider adding index for better performance
        $table->index(['bukua_user_id']);
    });
  2. Run migrations:

    php artisan migrate

User Model Configuration

Update your User model to include the Bukua fields:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'bukua_user_id',
        'bukua_access_token',
        'bukua_refresh_token',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
        'bukua_access_token',
        'bukua_refresh_token',
    ];
}

CORS Configuration

To handle cross-origin requests properly, configure your Laravel CORS settings in config/cors.php:

If your Laravel application doesn't have the CORS configuration file, generate it using:

php artisan config:publish cors

This will create the config/cors.php file if it doesn't already exist.

Update your config/cors.php file with the following settings:

return [
    'paths' => [
        'api/*',
        'sanctum/csrf-cookie',
        'bukua-auth/callback', // Bukua OAuth callback
    ],

    'allowed_methods' => ['*'],

    'allowed_origins' => [
        'https://bukua-core.apptempest.com', // Bukua development environment
        'https://app.bukuaplatform.com',     // Bukua production environment
    ],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [
        'X-Inertia-Location', // Bukua OAuth redirects
        'X-Inertia',          // Bukua OAuth responses
    ],

    'max_age' => 0,

    'supports_credentials' => false,
];

CORS Configuration Notes:

  • Ensure the paths array includes 'bukua-auth/callback' to handle OAuth callbacks
  • Add both Bukua domains to allowed_origins for proper cross-origin requests
  • Include 'X-Inertia-Location' and 'X-Inertia' in exposed_headers for OAuth redirection

Usage

Login Button Implementation

Blade Templates:

<!-- resources/views/auth/login.blade.php -->
@if (Route::has('bukua-auth.authorize'))
    <form action="{{ route('bukua-auth.authorize') }}" method="POST">
        @csrf
        <button type="submit" class="btn btn-primary">
            Login with Bukua
        </button>
    </form>
@endif

Inertia.js with React/Vue:

// For React components
import { Link } from '@inertiajs/react';

function LoginButton() {
    return (
        <Link 
            method="post" 
            href={route('bukua-auth.authorize')}
            as="button"
            className="btn btn-primary"
        >
            Login with Bukua
        </Link>
    );
}

Authentication Routes

The package automatically registers the following routes:

Route Name URL Method Purpose
bukua-auth.authorize /bukua/authorize POST Initiates OAuth flow
bukua-auth.callback /bukua/callback GET Handles OAuth callback

Events

The package dispatches events that you can listen for to extend functionality:

Available Events

  • BukuaUserLoggedInEvent: Dispatched when a user successfully logs in

Event Listener Setup

Create an example listener in Laravel using:

Name: HandleBukuaUserLoggedIn Event: \BukuaAuth\Events\BukuaUserLoggedInEvent:

php artisan make:listener

Example listener implementation:

<?php

namespace App\Listeners;

use BukuaAuth\Events\BukuaUserLoggedInEvent;
use BukuaAuth\Facades\BukuaAuth;
use Illuminate\Support\Facades\Log;

class HandleBukuaUserLoggedIn
{
    /**
     * Handle the event.
     */
    public function handle(BukuaUserLoggedInEvent $event)
    {
        $user = $event->user;
        
        // Log the event
        Log::info('Bukua user logged in', [
            'bukua_user_id' => $user->bukua_user_id,
            'timestamp' => now(),
        ]);

        try {
            // Fetch basic user profile
            $userProfile = BukuaAuth::me();

            $firstName   = $userProfile['response']['user']['first_name'];
            $schoolName  = $userProfile['response']['school']['name'];
            $schoolUid   = $userProfile['response']['school']['uid'];
            $roleName    = $userProfile['response']['role']['name'];
            $roleUid     = $userProfile['response']['role']['uid'];

            // Run your business logic ...                           
        } catch (\Exception $e) {
            Log::error('Failed to fetch user data from Bukua', [
                'error' => $e->getMessage(),
                'bukua_user_id' => $user->bukua_user_id,
            ]);
        }
    }
}

API Methods

The package provides several methods to interact with Bukua's API:

Basic User Profile

use BukuaAuth\Facades\BukuaAuth;

try {
    $userProfile = BukuaAuth::me();

    print_r($userProfile);
    
    // Returns: {
    //   user: {"uid": "user_uid", "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com"}
    //   school: {"uid": "school_uid", "name": "Jitahidi School"}
    //   role: {"uid": "role_uid", "name": "Teacher"}
    // }
    
} catch (\Exception $e) {
    echo "Error: " . $e->getMessage();
}

User Subjects

try {
    $subjects = BukuaAuth::subjects();

    print_r($subjects);
    
    // Returns array of subject objects: [
    //   {
    //     "uid": "subject_uid",
    //     "name": "Media Technology",
    //   }
    //   {
    //     "uid": "subject_uid",
    //     "name": "Fasihi ya Kiswahili",
    //   }
    //   {
    //     "uid": "subject_uid",
    //     "name": "Home Science",
    //   }
    // ]
    
} catch (\Exception $e) {
    echo "Error: " . $e->getMessage();
}

Troubleshooting

Common Issues

  1. "Invalid redirect_uri" error

    • Ensure BUKUA_USER_ACCESS_APP_URL matches exactly with your Bukua app credentials
    • App URL must use HTTPS and be accessible
  2. "Client authentication failed" error

    • Verify BUKUA_USER_ACCESS_CLIENT_ID and BUKUA_USER_ACCESS_CLIENT_SECRET are correct
    • Check for extra spaces in environment variables
  3. User model not found

    • Verify BUKUA_USER_MODEL points to the correct namespace
    • Ensure the User model exists and is accessible
  4. User creation errors

    • Check if users table already has the required columns
    • Ensure all existing fields in the users table are nullable as specified
  5. CORS issues

    • Verify bukua-auth/callback is added to CORS paths
    • Ensure Bukua domains are in allowed_origins
    • Check that X-Inertia headers are exposed

Support