digram/bukua-auth
Composer 安装命令:
composer require digram/bukua-auth
包简介
Login with Bukua OAuth for your Laravel application
README 文档
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:
-
Bukua Developer Account
- Register as an app developer at Bukua Platform - Development Environment or Bukua Platform - Production Environment
- Create a User Access App in the selected environment above
-
Application Credentials
- Obtain your
client_id,client_secretandapp_urlfrom the Bukua Developer Dashboard
- Obtain your
-
Laravel Application
- Laravel 8.x or higher
- Composer for dependency management
Installation
-
Install the package via Composer:
composer require digram/bukua-auth
-
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
-
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']); });
-
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
pathsarray includes'bukua-auth/callback'to handle OAuth callbacks - Add both Bukua domains to
allowed_originsfor proper cross-origin requests - Include
'X-Inertia-Location'and'X-Inertia'inexposed_headersfor 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 the authenticated user's Bukua profile $profile = BukuaAuth::me(); $data = $profile['response']; $firstName = $data['user']['first_name']; $workspaceName = $data['context']['name']; $workspaceUid = $data['context']['uid']; $appRoles = $data['app_roles'] ?? []; // 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. All responses use Bukua's standard envelope:
{
"code": 200,
"error": null,
"response": {}
}
Always read data from the response key. Errors appear in error with a non-200 code.
Basic User Profile
use BukuaAuth\Facades\BukuaAuth; try { $payload = BukuaAuth::me(); $profile = $payload['response']; print_r($profile); } catch (\Exception $e) { echo "Error: " . $e->getMessage(); }
Response shape
The profile reflects the user's active workspace on Bukua (school or organization tenant) and the app roles they hold in your app within that workspace.
{
"user": {
"uid": "01932f1a-…",
"first_name": "Jane",
"last_name": "Rose",
"email": "jane@example.com",
"avatar": { "thumb": "https://…", "medium": "https://…" },
"phone_number": "+254712345678"
},
"context": {
"kind": "school",
"uid": "01932f1a-…",
"name": "Jitahidi Secondary School",
"logo": "https://…",
"organization": {
"uid": "01932f1a-…",
"type": {
"uid": "01932f1a-…",
"name": "School",
"abbreviation": "SCH"
}
}
},
"app_roles": ["Teacher", "Class Admin"],
"enrolment_number": "ADM/2024/001",
"is_verified": true
}
Field reference
| Field | Description |
|---|---|
user |
Core identity fields for the logged-in Bukua user. |
user.phone_number |
Only present when the token includes the phones:view:own scope. Otherwise null. |
context |
The user's currently active workspace. |
context.kind |
"school" or "organization". |
context.uid |
UID of the active workspace entity (school UID when kind is school, organization UID when kind is organization). |
context.name |
Display name of the active workspace. |
context.logo |
Logo URL for the workspace, or null. |
context.organization |
Parent tenant. For school workspaces this is the owning organization; for organization workspaces it is the organization itself. |
app_roles |
Role names this user holds in your app only, within the active workspace (e.g. ["Teacher"], ["Teacher", "Class Admin"], or []). |
enrolment_number |
Admission or membership number in the active workspace, when applicable. |
is_verified |
Whether the user's enrolment in the active workspace is verified. |
Common integration patterns
Read the user's roles in your app
app_roles is a flat array of role name strings, already scoped to your app:
$profile = BukuaAuth::me()['response']; $appRoles = $profile['app_roles'] ?? []; // e.g. ["Teacher"] or ["Teacher", "Class Admin"] if (in_array('Teacher', $appRoles, true)) { // ... }
An empty array means the user has no assigned roles in your app for their current workspace.
Resolve the active school
When context.kind is "school", the school is the workspace itself:
$context = $profile['context']; if ($context['kind'] === 'school') { $schoolUid = $context['uid']; $schoolName = $context['name']; $organizationUid = $context['organization']['uid']; }
When context.kind is "organization", the user is working at the organization level (no single school selected).
Required OAuth scopes
| Endpoint | Scope |
|---|---|
me |
profiles:view:own |
| Phone number field | phones:view:own (optional) |
Error responses
| HTTP code | Meaning |
|---|---|
401 |
Missing or invalid access token. |
403 |
Token is valid but lacks profiles:view:own. |
404 |
User has no active workspace on Bukua. Prompt them to select or join a school/organization first. |
User Subjects
Only available when the user's active workspace is a school. Requires the subjects:view:own scope.
try { $payload = BukuaAuth::subjects(); $subjects = $payload['response']['subjects']; print_r($subjects); } catch (\Exception $e) { echo "Error: " . $e->getMessage(); }
Example subject object:
{
"uid": "01932f1a-…",
"name": "Mathematics",
"school_level": {
"uid": "01932f1a-…",
"name": "Form 3"
},
"role": {
"uid": "01932f1a-…",
"name": "Teacher"
}
}
Returns 404 when the active workspace is not a school or the user has no enrolled subjects.
Troubleshooting
Common Issues
-
"Invalid redirect_uri" error
- Ensure
BUKUA_USER_ACCESS_APP_URLmatches exactly with your Bukua app credentials - App URL must use HTTPS and be accessible
- Ensure
-
"Client authentication failed" error
- Verify
BUKUA_USER_ACCESS_CLIENT_IDandBUKUA_USER_ACCESS_CLIENT_SECRETare correct - Check for extra spaces in environment variables
- Verify
-
User model not found
- Verify
BUKUA_USER_MODELpoints to the correct namespace - Ensure the User model exists and is accessible
- Verify
-
User creation errors
- Check if users table already has the required columns
- Ensure all existing fields in the users table are nullable as specified
-
CORS issues
- Verify
bukua-auth/callbackis added to CORS paths - Ensure Bukua domains are in allowed_origins
- Check that X-Inertia headers are exposed
- Verify
Support
- Support Email: hello@bukuaplatform.com
- Issue Tracking: GitHub Issues
统计信息
- 总下载量: 159
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: Apache-2.0
- 更新时间: 2025-05-09