useAuth.js 1.46 KB
import { ref } from 'vue'
import axios from 'axios'

const user = ref(null)
const isChecked = ref(false) // 是否已经问过一次 /api/auth/me,避免路由守卫重复请求
let checkPromise = null

export function useAuth() {
  /** 查一次当前登录态,结果缓存到下次显式 refresh。未登录返回 null,不算错误。 */
  async function checkAuth({ force = false } = {}) {
    if (isChecked.value && !force) return user.value
    if (checkPromise && !force) return checkPromise

    checkPromise = axios.get('/api/auth/me')
      .then(({ data }) => {
        user.value = data.user || null
        isChecked.value = true
        return user.value
      })
      .catch(() => {
        user.value = null
        isChecked.value = true
        return null
      })
      .finally(() => { checkPromise = null })

    return checkPromise
  }

  async function login(email, password) {
    const { data } = await axios.post('/api/auth/login', { email, password })
    user.value = data.user
    isChecked.value = true
    return data.user
  }

  async function logout() {
    try { await axios.post('/api/auth/logout') } catch { /* cookie 清不掉也要清本地状态 */ }
    user.value = null
    isChecked.value = true
  }

  /** 401 拦截器触发时调用:本地登录态失效,不用再打一次 /me 去确认 */
  function clearAuth() {
    user.value = null
    isChecked.value = true
  }

  return { user, isChecked, checkAuth, login, logout, clearAuth }
}