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

Laravel+Vue.js单页应用(SPA)需在何处进行身份认证?

Great question—this is a super common hurdle when transitioning from a traditional Laravel+Blade app to an SPA. Let’s break this down step by step:

Where to Handle Authentication? Both PHP and Vue Routes, But for Different Reasons

1. PHP Backend (API Routes): Your Security Foundation

This is non-negotiable—all sensitive API endpoints must be protected by Laravel’s authentication middleware (like auth:sanctum or auth:api). Frontend code can always be tampered with, so your backend needs to validate every incoming request’s legitimacy on its own.

For example, define your protected API routes like this:

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/api/user', fn (Request $request) => $request->user());
    Route::put('/api/posts/{post}', [PostController::class, 'update']);
    // All other endpoints that require authentication
});

2. Vue Frontend (Vue Router): For User Experience

While the backend handles actual security, Vue routes handle UI-level access control to keep unauthenticated users from seeing pages they shouldn’t. Use Vue Router’s navigation guards to check login status before navigating to protected routes.

Here’s a quick example:

// In your router setup
router.beforeEach((to, from, next) => {
    const isLoggedIn = localStorage.getItem('auth_token') !== null;
    // Check if the route requires auth and user isn't logged in
    if (to.meta.requiresAuth && !isLoggedIn) {
        next('/login');
    } else {
        next();
    }
});

// And mark routes as protected in your route config
const routes = [
    { path: '/dashboard', component: Dashboard, meta: { requiresAuth: true } },
    { path: '/login', component: Login },
];
How to Reuse Laravel’s Permissions & Session Logic in Vue

If you were using Laravel’s default session auth, Sanctum is the perfect drop-in for SPAs—it’s built specifically for this use case:

  • Set up Sanctum on the backend, then create a login endpoint that returns an auth token (or use cookie-based auth, which is more secure for same-domain SPAs).
  • Store the token in localStorage or a secure cookie on the frontend, then attach it to every API request (use an Axios interceptor to automate this):
    axios.interceptors.request.use(config => {
        const token = localStorage.getItem('auth_token');
        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
    });
    
  • Backend session logic works just like before—Auth::user() will still return the authenticated user, and session expiration is handled by Sanctum’s token settings.

2. Permissions: Frontend UI Checks + Backend Enforcement

Never rely solely on frontend permission checks—the backend must validate permissions for every sensitive action. But frontend checks improve UX by hiding unavailable actions or routes.

Backend (Keep Using Laravel Gates/Policies)

Continue using Laravel’s built-in Gates or Policies to enforce permissions on the server side:

// In your PostController
public function update(Post $post)
{
    // Use a Policy to verify the user can update this post
    $this->authorize('update', $post);
    // Proceed with the update logic
}

Frontend (Cache & Check Permissions)

After login, fetch the user’s permissions from an API endpoint (e.g., /api/user/permissions) and store them in a state management tool like Pinia or Vuex. Then use this data to conditionally render UI elements:

<template>
    <div>
        <button v-if="can('update_post')" @click="editPost">Edit Post</button>
    </div>
</template>

<script setup>
import { useUserStore } from '@/stores/user';
const userStore = useUserStore();

const can = (permission) => {
    return userStore.permissions.includes(permission);
};
</script>

3. Handling Session Expiration

Set up an Axios response interceptor to catch 401 Unauthorized errors, clear the local token, and redirect to the login page:

axios.interceptors.response.use(
    response => response,
    error => {
        if (error.response?.status === 401) {
            localStorage.removeItem('auth_token');
            router.push('/login');
        }
        return Promise.reject(error);
    }
);

内容的提问来源于stack exchange,提问作者Felipe Paz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:48:20