Laravel 10+Vue3单项目结构规划与Sanctum认证方案咨询
项目结构规划与Sanctum多场景认证方案
一、项目结构规划
按照你的需求,调整Laravel目录结构如下(注意规避Laravel默认/app目录的命名冲突):
目录拆分
/frontend(替代你提到的/app,避免和Laravel核心/app目录冲突;若坚持用/app,需修改composer.json的自动加载规则)/frontend/src:Vue3组件、路由、Pinia状态管理等核心代码/frontend/public:前端编译产物目录(配置Vite编译到Laravel的public/frontend下)/frontend/package.json、vite.config.js:前端依赖与构建配置
/admin模块(基于Laravel+Blade)- 控制器:
app/Http/Controllers/Admin/ - 视图:
resources/views/admin/ - 路由:
routes/admin.php(需在RouteServiceProvider中注册)
- 控制器:
/api接口模块- 控制器:
app/Http/Controllers/Api/ - 路由:
routes/api.php(Laravel默认已注册)
- 控制器:
Vite构建配置
修改vite.config.js实现前后端代理与资源输出:
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], build: { outDir: '../public/frontend', emptyOutDir: true, }, server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8000', changeOrigin: true, }, '/sanctum': { target: 'http://localhost:8000', changeOrigin: true, }, }, }, })
二、Sanctum同时实现API与后台认证
完全可以用Sanctum覆盖两种认证场景,核心是利用它支持的Session认证(Blade后台)和SPA Cookie认证(Vue3前端),共享同一用户表,通过字段区分权限。
1. 基础配置
安装并初始化Sanctum:
composer require laravel/sanctum php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" php artisan migrate
确保config/auth.php的守卫配置正确:
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'sanctum', 'provider' => 'users', 'hash' => false, ], ],
2. 后台Blade管理员认证
后台用传统Session认证,基于web守卫:
- 注册后台路由(
routes/admin.php):
Route::prefix('admin')->middleware('web')->group(function () { // 登录页 Route::get('/login', [\App\Http\Controllers\Admin\AuthController::class, 'showLoginForm'])->name('admin.login'); Route::post('/login', [\App\Http\Controllers\Admin\AuthController::class, 'login']); Route::post('/logout', [\App\Http\Controllers\Admin\AuthController::class, 'logout'])->name('admin.logout')->middleware('auth:web'); // 后台受保护路由 Route::middleware('auth:web')->group(function () { Route::get('/dashboard', fn() => view('admin.dashboard'))->name('admin.dashboard'); // 用户管理、应用设置等路由 }); });
- 后台登录控制器逻辑(验证管理员权限):
namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class AuthController extends Controller { public function showLoginForm() { return view('admin.login'); } public function login(Request $request) { $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); if (Auth::guard('web')->attempt($request->only('email', 'password'))) { $user = Auth::user(); // 检查是否为管理员(需在users表添加is_admin字段) if (!$user->is_admin) { Auth::logout(); return back()->withErrors(['email' => '无后台访问权限']); } $request->session()->regenerate(); return redirect()->intended(route('admin.dashboard')); } return back()->withErrors(['email' => '账号或密码错误']); } public function logout(Request $request) { Auth::guard('web')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect(route('admin.login')); } }
3. Vue3前端API认证
前端用Sanctum的SPA Cookie认证模式:
- 配置CORS(
config/cors.php):
return [ 'paths' => ['api/*', 'sanctum/csrf-cookie'], 'allowed_methods' => ['*'], 'allowed_origins' => ['http://localhost:5173'], 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, ];
- Vue3登录逻辑示例:
// 获取CSRF令牌 async function getCsrfToken() { await fetch('/sanctum/csrf-cookie', { credentials: 'include' }); } // 用户登录 async function login(email, password) { await getCsrfToken(); const res = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ email, password }) }); return res.json(); } // 获取当前用户信息 async function getCurrentUser() { const res = await fetch('/api/user', { credentials: 'include' }); return res.json(); }
- API路由与控制器:
// routes/api.php Route::post('/login', [\App\Http\Controllers\Api\AuthController::class, 'login']); Route::post('/logout', [\App\Http\Controllers\Api\AuthController::class, 'logout'])->middleware('auth:sanctum'); Route::middleware('auth:sanctum')->group(function () { Route::get('/user', fn(Request $request) => $request->user()); // 其他业务接口 });
// app/Http/Controllers/Api/AuthController.php namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class AuthController extends Controller { public function login(Request $request) { $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); if (!Auth::attempt($request->only('email', 'password'))) { return response()->json(['message' => '账号或密码错误'], 401); } return response()->json(Auth::user()); } public function logout(Request $request) { Auth::guard('web')->logout(); return response()->json(['message' => '退出成功']); } }
关键注意事项
- 后台用
web守卫(Session),前端API用api守卫(Sanctum Cookie),两者共享users表,通过is_admin字段区分权限。 - 若需更细粒度权限控制,可搭配Laravel的Gate/Policy实现。
内容的提问来源于stack exchange,提问作者Udders
相关产品推荐
相关产品推荐

