반응형
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import axios from 'axios'
import { useRouter } from 'vue-router'
export const useAuthStore = defineStore('auth', () => {
// 상태 (State)
const user = ref(null)
const token = ref(localStorage.getItem('jwt-token'))
const loading = ref(false)
const error = ref('')
// 계산된 속성 (Getters)
const isAuthenticated = computed(() => !!token.value && !!user.value)
const userEmail = computed(() => user.value?.email || '')
const userName = computed(() => user.value?.name || '')
const userRoles = computed(() => user.value?.roles || [])
const isAdmin = computed(() => userRoles.value.includes('ROLE_ADMIN'))
const isManager = computed(() => userRoles.value.includes('ROLE_MANAGER'))
// 액션 (Actions)
const login = async (credentials) => {
loading.value = true
error.value = ''
try {
const response = await axios.post('/api/authenticate', credentials)
if (response.data.jwt) {
// 토큰 저장
token.value = response.data.jwt
localStorage.setItem('jwt-token', response.data.jwt)
// axios 헤더 설정
setAuthToken(response.data.jwt)
// 사용자 정보 저장
user.value = {
email: response.data.email || credentials.email,
name: response.data.name || '',
roles: response.data.roles || ['ROLE_USER'],
id: response.data.userId || null
}
// 사용자 정보를 localStorage에도 저장 (새로고침 대응)
localStorage.setItem('user-info', JSON.stringify(user.value))
return { success: true }
}
} catch (err) {
error.value = err.response?.status === 401
? '이메일 또는 비밀번호가 올바르지 않습니다.'
: '로그인 중 오류가 발생했습니다.'
return { success: false, error: error.value }
} finally {
loading.value = false
}
}
const logout = async () => {
loading.value = true
try {
// 서버에 로그아웃 요청
await axios.post('/api/logout')
} catch (err) {
console.error('로그아웃 API 호출 실패:', err)
} finally {
// 로컬 상태 정리
clearAuthData()
loading.value = false
}
}
const fetchUserProfile = async () => {
if (!token.value) return
loading.value = true
try {
const response = await axios.get('/api/user/profile')
user.value = {
...user.value,
...response.data
}
localStorage.setItem('user-info', JSON.stringify(user.value))
} catch (err) {
console.error('사용자 프로필 가져오기 실패:', err)
if (err.response?.status === 401) {
clearAuthData()
}
} finally {
loading.value = false
}
}
const updateUserProfile = async (profileData) => {
loading.value = true
try {
const response = await axios.put('/api/user/profile', profileData)
user.value = { ...user.value, ...response.data }
localStorage.setItem('user-info', JSON.stringify(user.value))
return { success: true }
} catch (err) {
error.value = '프로필 업데이트 중 오류가 발생했습니다.'
return { success: false, error: error.value }
} finally {
loading.value = false
}
}
const clearAuthData = () => {
user.value = null
token.value = null
error.value = ''
localStorage.removeItem('jwt-token')
localStorage.removeItem('user-info')
delete axios.defaults.headers.common['Authorization']
}
const setAuthToken = (authToken) => {
if (authToken) {
axios.defaults.headers.common['Authorization'] = `Bearer ${authToken}`
} else {
delete axios.defaults.headers.common['Authorization']
}
}
const initializeAuth = () => {
const savedToken = localStorage.getItem('jwt-token')
const savedUser = localStorage.getItem('user-info')
if (savedToken && savedUser) {
token.value = savedToken
user.value = JSON.parse(savedUser)
setAuthToken(savedToken)
// 사용자 정보 갱신 (선택적)
fetchUserProfile()
}
}
return {
// 상태
user,
token,
loading,
error,
// 계산된 속성
isAuthenticated,
userEmail,
userName,
userRoles,
isAdmin,
isManager,
// 액션
login,
logout,
fetchUserProfile,
updateUserProfile,
clearAuthData,
initializeAuth
}
})
반응형