Nyavokevin eec6c974c9
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
fix safari
2025-10-03 18:57:04 +03:00

7.7 KiB

Authentication Setup Guide

This document explains the authentication system that has been set up for your Laravel + Inertia.js + Vue 3 application.

📦 What Was Installed/Created

Files Created:

  1. resources/js/services/authService.ts - API service for authentication
  2. resources/js/stores/auth.ts - Pinia store for auth state management
  3. resources/js/middleware/auth.ts - Route guards for authentication
  4. resources/js/composables/useAuthGuard.ts - Composables for protecting routes
  5. resources/js/components/LoginExample.vue - Example login component

Files Modified:

  • resources/js/app.ts - Integrated auth guards

🔧 Setup

Note: Pinia instead of Vuex

Your project already has Pinia installed, which is the official state management solution for Vue 3 (and the successor to Vuex). The setup uses Pinia instead of Vuex as requested.

If you specifically need Vuex 4, run:

npm install vuex@4

However, Pinia is recommended for Vue 3 projects.

🚀 Usage

1. Using the Auth Store

The auth store provides all authentication functionality:

<script setup lang="ts">
import { useAuthStore } from '@/stores/auth';

const authStore = useAuthStore();

// Login
async function login() {
    const success = await authStore.login({
        email: 'user@example.com',
        password: 'password',
        remember: true
    });
    
    if (success) {
        // Redirect or show success message
    } else {
        console.error(authStore.error);
    }
}

// Logout
async function logout() {
    await authStore.logout();
}

// Check authentication status
console.log(authStore.isAuthenticated);
console.log(authStore.currentUser);
</script>

2. Protecting Routes with Composables

Protect authenticated routes (dashboard, profile, etc.):

<script setup lang="ts">
import { useAuthGuard } from '@/composables/useAuthGuard';

// This will redirect to /login if user is not authenticated
useAuthGuard();
</script>

<template>
    <div>
        <h1>Protected Dashboard</h1>
    </div>
</template>

Protect guest routes (login, register):

<script setup lang="ts">
import { useGuestGuard } from '@/composables/useAuthGuard';

// This will redirect to /dashboard if user is already authenticated
useGuestGuard();
</script>

<template>
    <div>
        <h1>Login Page</h1>
    </div>
</template>

3. Accessing User Data

<script setup lang="ts">
import { useAuthStore } from '@/stores/auth';

const authStore = useAuthStore();
</script>

<template>
    <div v-if="authStore.isAuthenticated">
        <p>Welcome, {{ authStore.currentUser?.name }}!</p>
        <p>Email: {{ authStore.currentUser?.email }}</p>
        <button @click="authStore.logout">Logout</button>
    </div>
    <div v-else>
        <p>Please log in</p>
    </div>
</template>

4. Auth Store API

The auth store (useAuthStore()) provides:

State:

  • user - Current user object or null
  • token - Authentication token (if API returns one)
  • loading - Loading state
  • error - Error message

Getters:

  • isAuthenticated - Boolean indicating if user is logged in
  • currentUser - Current user object

Actions:

  • login(credentials) - Login with email and password
  • logout() - Logout current user
  • checkAuth() - Check if user is authenticated
  • fetchUser() - Fetch current user data
  • clearError() - Clear error messages
  • setUser(user) - Manually set user data

🔐 API Endpoints

The auth service expects these endpoints:

Login

POST http://localhost:8000/api/auth/login
Body: {
    "email": "user@example.com",
    "password": "password",
    "remember": true
}

Response: {
    "user": {
        "id": 1,
        "name": "John Doe",
        "email": "user@example.com",
        ...
    },
    "token": "optional-auth-token"
}

Logout

POST http://localhost:8000/api/auth/logout

Get Current User

GET http://localhost:8000/api/auth/user

Response: {
    "user": {
        "id": 1,
        "name": "John Doe",
        "email": "user@example.com",
        ...
    }
}

🛠️ Backend Setup (Laravel)

You need to create these API routes in Laravel. Here's an example:

// routes/api.php
use App\Http\Controllers\Auth\ApiAuthController;

Route::prefix('auth')->group(function () {
    Route::post('/login', [ApiAuthController::class, 'login']);
    Route::post('/logout', [ApiAuthController::class, 'logout'])->middleware('auth:sanctum');
    Route::get('/user', [ApiAuthController::class, 'user'])->middleware('auth:sanctum');
});

Example controller:

// app/Http/Controllers/Auth/ApiAuthController.php
namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class ApiAuthController extends Controller
{
    public function login(Request $request)
    {
        $credentials = $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        if (Auth::attempt($credentials, $request->boolean('remember'))) {
            $user = Auth::user();
            $token = $user->createToken('auth-token')->plainTextToken;

            return response()->json([
                'user' => $user,
                'token' => $token,
            ]);
        }

        return response()->json([
            'message' => 'Invalid credentials',
        ], 401);
    }

    public function logout(Request $request)
    {
        $request->user()->currentAccessToken()->delete();
        return response()->json(['message' => 'Logged out successfully']);
    }

    public function user(Request $request)
    {
        return response()->json(['user' => $request->user()]);
    }
}

💾 Persistence

The auth store automatically persists the user and token to localStorage using pinia-plugin-persistedstate. This means:

  • User stays logged in after page refresh
  • Auth state is restored on app load
  • Logout clears the persisted data

🎯 Example: Update Your Login Page

Update your existing resources/js/pages/auth/Login.vue:

<script setup lang="ts">
import { useAuthStore } from '@/stores/auth';
import { useGuestGuard } from '@/composables/useAuthGuard';
import { router } from '@inertiajs/vue3';
import { ref } from 'vue';

// Redirect if already authenticated
useGuestGuard();

const authStore = useAuthStore();
const email = ref('');
const password = ref('');
const remember = ref(false);

async function handleLogin() {
    const success = await authStore.login({
        email: email.value,
        password: password.value,
        remember: remember.value,
    });

    if (success) {
        router.get('/dashboard');
    }
}
</script>

🎯 Example: Protect Dashboard

Update your dashboard to require authentication:

<script setup lang="ts">
import { useAuthGuard } from '@/composables/useAuthGuard';

// This will redirect to login if not authenticated
useAuthGuard();
</script>

<template>
    <div>
        <h1>Dashboard</h1>
        <!-- Your dashboard content -->
    </div>
</template>

📝 Notes

  1. Axios is already installed in your project at version 1.11.0
  2. Pinia is already installed and configured with persistence
  3. The auth system works with your existing Inertia.js setup
  4. CSRF tokens are automatically handled via the existing resources/js/lib/http.ts
  5. Authentication state persists across page reloads

🔄 Customization

Change API URLs

Edit resources/js/services/authService.ts to change the API endpoints.

Change Redirect Routes

Edit the composables in resources/js/composables/useAuthGuard.ts to change default redirect routes.

Add More User Fields

Update the User interface in resources/js/services/authService.ts to match your user model.