Авторизація на фронтенді з використанням Vue 3 може бути організована через керування станом користувача та взаємодію з сервером (зазвичай через API). Ось базова структура авторизації для Vue 3:
1. Налаштування маршрутизації (Vue Router)
Маршрути поділяються на публічні та приватні. Приватні маршрути повинні бути доступні лише для авторизованих користувачів.
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from './stores/auth'
const routes = [
{
path: '/login',
name: 'Login',
component: () => import('./views/Login.vue')
},
{
path: '/dashboard',
name: 'Dashboard',
component: () => import('./views/Dashboard.vue'),
meta: { requiresAuth: true } // приватний маршрут
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
// Глобальний захист маршрутів
router.beforeEach((to, from, next) => {
const authStore = useAuthStore()
if (to.meta.requiresAuth && !authStore.isAuthenticated) {
next({ name: 'Login' }) // перенаправляє на сторінку входу
} else {
next()
}
})
export default router
2. Менеджмент стану користувача (Pinia)
Замість Vuex, тепер використовується Pinia для керування станом авторизації.
Створення стору авторизації:
// stores/auth.js
import { defineStore } from 'pinia'
import axios from 'axios'
export const useAuthStore = defineStore('auth', {
state: () => ({
token: localStorage.getItem('token') || '',
user: null
}),
actions: {
async login(credentials) {
const response = await axios.post('/api/login', credentials)
const token = response.data.token
localStorage.setItem('token', token)
this.token = token
await this.fetchUser()
},
async fetchUser() {
const response = await axios.get('/api/user', {
headers: {
Authorization: `Bearer ${this.token}`
}
})
this.user = response.data
},
logout() {
this.token = ''
this.user = null
localStorage.removeItem('token')
}
},
getters: {
isAuthenticated: (state) => !!state.token,
user: (state) => state.user
}
})
3. Захист запитів API (Axios інтерцептор)
Додаємо інтерцептор для автоматичного додавання токена до кожного запиту.
import axios from 'axios'
import { useAuthStore } from './stores/auth'
axios.interceptors.request.use((config) => {
const authStore = useAuthStore()
if (authStore.isAuthenticated) {
config.headers.Authorization = `Bearer ${authStore.token}`
}
return config
}, (error) => {
return Promise.reject(error)
})
4. Компонент входу (Login.vue)
Компонент для введення логіну та пароля:
<template>
<div>
<form @submit.prevent="login">
<input v-model="email" type="email" placeholder="Email">
<input v-model="password" type="password" placeholder="Password">
<button type="submit">Login</button>
</form>
</div>
</template>
<script>
import { useAuthStore } from '../stores/auth'
export default {
data() {
return {
email: '',
password: ''
}
},
setup() {
const authStore = useAuthStore()
const login = async () => {
try {
await authStore.login({ email: email.value, password: password.value })
this.$router.push({ name: 'Dashboard' })
} catch (error) {
console.error('Login failed:', error)
}
}
return {
email,
password,
login
}
}
}
</script>
5. Вихід та обробка помилок
Для обробки помилок автентифікації та виходу з системи використовуйте дії logout
та додатково обробляйте помилки у запитах.
Висновок
- Pinia для менеджменту стану користувача.
- Маршрутизація захищена, перевіряє доступ до сторінок.
- Axios інтерцептор для додавання токена в заголовки запитів.
- Компоненти входу використовують Pinia для управління логікою входу.
- Вихід та обробка помилок через Pinia.
Ця структура забезпечує гнучкість і безпеку під час роботи з авторизацією на фронтенді з Vue 3 та Pinia.