반응형
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import axios from 'axios'
export const useAuthStore = defineStore('auth', () => {
// 상태
const user = ref(null)
const token = ref(localStorage.getItem('jwt-token'))
const loading = ref(false)
const error = ref('')
const initialized = ref(false) // 초기화 상태 추가
// 계산된 속성
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 initializeAuth = async () => {
if (initialized.value) return
loading.value = true
try {
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)
// 토큰 유효성 검사
try {
await axios.get('/api/user/profile')
// 토큰이 유효하면 사용자 정보 최신화
} catch (error) {
if (error.response?.status === 401) {
// 토큰이 만료되었거나 유효하지 않음
clearAuthData()
}
}
}
} catch (error) {
console.error('인증 초기화 실패:', error)
clearAuthData()
} finally {
loading.value = false
initialized.value = true
}
}
// 로그인
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
user.value = {
email: response.data.email || credentials.email,
name: response.data.name || '',
roles: response.data.roles || ['ROLE_USER'],
id: response.data.userId || null
}
localStorage.setItem('jwt-token', response.data.jwt)
localStorage.setItem('user-info', JSON.stringify(user.value))
setAuthToken(response.data.jwt)
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 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']
}
}
return {
// 상태
user,
token,
loading,
error,
initialized,
// 계산된 속성
isAuthenticated,
userEmail,
userName,
userRoles,
isAdmin,
// 액션
login,
logout,
initializeAuth,
clearAuthData
}
})
반응형