Laravel从AppsManager API读取数据库凭证:是否为最佳实践及实现方法
How to implement this in Laravel
Here’s a step-by-step implementation that handles credential fetching, caching, and fallback:
1. Set up basic environment variables for AppsManager API access
First, add these to your Laravel app’s .env file (these are your app’s credentials to authenticate with AppsManager, not the database credentials):
APPS_MANAGER_API_URL=https://your-apps-manager-domain.com APPS_MANAGER_API_KEY=your-secure-api-key-here # Optional fallback credentials for when API is unreachable DB_FALLBACK_HOST=localhost DB_FALLBACK_DATABASE=laravel DB_FALLBACK_USERNAME=root DB_FALLBACK_PASSWORD=
2. Create a service to fetch credentials from AppsManager
Create a new service class at app/Services/AppsManagerCredentialFetcher.php:
<?php namespace App\Services; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Http; use Exception; class AppsManagerCredentialFetcher { public function getDatabaseCredentials(): array { // Cache credentials for 1 hour to reduce API calls return Cache::remember('database_credentials', 3600, function () { $response = Http::withToken(env('APPS_MANAGER_API_KEY')) ->get("{$this->getApiUrl()}/api/database-credentials"); // Handle API failure: return fallback credentials or throw exception if (!$response->successful()) { // Option 1: Fallback to local env variables return $this->getFallbackCredentials(); // Option 2: Throw an exception to halt app (use if fallback isn't allowed) // throw new Exception("Failed to fetch credentials: {$response->status()} {$response->body()}"); } return $response->json(); }); } private function getApiUrl(): string { return rtrim(env('APPS_MANAGER_API_URL'), '/'); } private function getFallbackCredentials(): array { return [ 'host' => env('DB_FALLBACK_HOST'), 'database' => env('DB_FALLBACK_DATABASE'), 'username' => env('DB_FALLBACK_USERNAME'), 'password' => env('DB_FALLBACK_PASSWORD'), ]; } }
3. Override Laravel's database configuration at boot time
We need to update the database config before Laravel initializes the database connection. The best place for this is the register method of your AppServiceProvider (since it runs before app booting and database connection setup):
Edit app/Providers/AppServiceProvider.php:
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\Config; use App\Services\AppsManagerCredentialFetcher; class AppServiceProvider extends ServiceProvider { /** * Register any application services. */ public function register(): void { // Fetch credentials from AppsManager $credentials = $this->app->make(AppsManagerCredentialFetcher::class)->getDatabaseCredentials(); // Override the default MySQL connection config Config::set('database.connections.mysql.host', $credentials['host']); Config::set('database.connections.mysql.database', $credentials['database']); Config::set('database.connections.mysql.username', $credentials['username']); Config::set('database.connections.mysql.password', $credentials['password']); // If you use other connection types (e.g., PostgreSQL), update those too // Config::set('database.connections.pgsql.host', $credentials['host']); // ... } /** * Bootstrap any application services. */ public function boot(): void { // ... existing boot logic } }
4. Test the implementation
- Start your Laravel app and verify it connects to the database using credentials from AppsManager.
- Test the fallback scenario by shutting down AppsManager or invalidating the API key—your app should switch to the fallback credentials if you chose option 1 in the service class.
- Check the Laravel cache to ensure credentials are being cached (use
php artisan cache:show database_credentialsto inspect the cached value).
Additional considerations
- Cache invalidation: Add an endpoint in AppsManager to trigger cache invalidation in dependent apps, or use a shorter cache TTL if credentials change frequently.
- Mutual TLS (mTLS): For extra security, use mTLS between Laravel and AppsManager to ensure only trusted apps can access the credential API.
- Command-line compatibility: This logic works for artisan commands (like
migrateorqueue:work) since the service provider runs in all environments.
内容的提问来源于stack exchange,提问作者Alin Ungurean
相关产品推荐
相关产品推荐

