You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 23:28:00