单Laravel应用能否在主域与子域分设博客、商城并共享认证体系?
Absolutely, this setup is totally feasible with Laravel—let me walk you through exactly how to make it work, covering all the key parts you need to consider:
1. Route Separation by Domain
First, split your routes into groups tied to each domain. Open routes/web.php and structure it like this:
// Main domain (blog) routes Route::domain('domain.com')->group(function () { // Blog-specific routes - e.g., post listings, author pages Route::get('/', 'BlogController@index')->name('blog.home'); Route::get('/posts/{slug}', 'BlogController@showPost')->name('blog.post.show'); // Blog admin routes (protected by auth/permissions) Route::middleware(['auth'])->group(function () { Route::get('/dashboard/posts', 'BlogAdminController@index')->name('blog.admin.posts'); }); }); // Subdomain (store) routes Route::domain('store.domain.com')->group(function () { // Store-specific routes - e.g., product listings, cart Route::get('/', 'StoreController@index')->name('store.home'); Route::get('/products/{sku}', 'StoreController@showProduct')->name('store.product.show'); // Store admin routes (protected by auth/permissions) Route::middleware(['auth'])->group(function () { Route::get('/dashboard/inventory', 'StoreAdminController@index')->name('store.admin.inventory'); }); });
This ensures requests to each domain hit the right controllers and business logic.
2. Conditional Extension Loading
You don’t need separate apps for different extensions—just load them conditionally using a custom service provider.
Create app/Providers/ConditionalServiceProvider.php:
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class ConditionalServiceProvider extends ServiceProvider { public function register() { $currentDomain = request()->getHost(); // Load blog-only extensions if ($currentDomain === 'domain.com') { $this->app->register(\Spatie\LaravelMarkdown\MarkdownServiceProvider::class); // Add other blog extensions here } // Load store-only extensions if ($currentDomain === 'store.domain.com') { $this->app->register(\Laravel\Cashier\CashierServiceProvider::class); $this->app->register(\Spatie\MediaLibrary\MediaLibraryServiceProvider::class); // Add other store extensions here } } }
Add this provider to your config/app.php providers array. This way, extensions only initialize for their target domain, keeping your app lean.
3. Shared Authentication & Permissions
This is straightforward with Laravel’s built-in tools, but you need one critical config tweak:
Update Session Domain: In your
.envfile, set:SESSION_DOMAIN=.domain.comThe leading dot ensures the session cookie is shared across all subdomains of
domain.com—so users log in once and stay authenticated on both sites.Shared Permissions: Use a package like Spatie’s Laravel Permission (or build your own) to manage roles. Since both domains use the same database, permissions are automatically shared. For example:
// Blog route with permission check Route::get('/dashboard/posts', 'BlogAdminController@index') ->middleware(['auth', 'permission:manage blog content']); // Store route with permission check Route::get('/dashboard/inventory', 'StoreAdminController@index') ->middleware(['auth', 'permission:manage store inventory']);A single user can have both blog and store permissions, or just one—your choice.
4. Environment & Configuration Isolation
Even with one app, you might want domain-specific settings (like site names or mail templates). Handle this dynamically:
Dynamic Config Values: In
config/app.php, set values based on the current domain:return [ 'name' => request()->getHost() === 'store.domain.com' ? 'Our Online Store' : 'Our Tech Blog', // Other domain-specific configs here ];Separate Config Files: Create
config/blog.phpandconfig/store.phpfor domain-specific settings, then load them conditionally in your custom service provider.
5. Server Deployment Setup
Make sure your web server (Nginx/Apache) routes both domains to the same Laravel app’s public directory. Here’s an example Nginx config:
# Main domain (blog) server { listen 80; listen [::]:80; server_name domain.com; root /var/www/your-laravel-app/public; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.2-fpm.sock; } } # Subdomain (store) server { listen 80; listen [::]:80; server_name store.domain.com; root /var/www/your-laravel-app/public; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.2-fpm.sock; } }
Don’t forget to enable SSL for both domains with Let’s Encrypt if you haven’t already!
Final Notes
This setup keeps your codebase unified, reduces maintenance overhead, and fully leverages Laravel’s flexibility. You’ll have a single app with isolated business logic, shared auth, and domain-specific extensions—exactly what you’re looking for.
内容的提问来源于stack exchange,提问作者mafortis

