You need to sign in or sign up before continuing.
auth_user_info.js 3.85 KB
/**
 * 对用户信息进行认证
 * @param {*} input 用户信息对象,包含 user_id 和 HTTP_USER_TOKEN 字段
 * @param {*} options 选项对象,包含 set_auth_headers 和 storage 字段
 * @returns 如果用户信息有效,则返回 true;否则返回 false
 */
export const applyUserInfoAuth = (input, options = {}) => {
  const user_info = input && input.data && input.data.user_info ? input.data.user_info : input
  if (!user_info || typeof user_info !== 'object') {
    return false
  }

  const { user_id, HTTP_USER_TOKEN } = user_info
  if (!user_id || !HTTP_USER_TOKEN) {
    return false
  }

  const set_auth_headers = options.set_auth_headers
  if (typeof set_auth_headers === 'function') {
    set_auth_headers(user_id, HTTP_USER_TOKEN)
  }

  const storage = Object.prototype.hasOwnProperty.call(options, 'storage') ? options.storage : globalThis.localStorage
  if (storage && typeof storage.setItem === 'function') {
    storage.setItem('user_info', JSON.stringify(user_info || {}))
  }

  if (storage === globalThis.localStorage) {
    cached_user_info_str = JSON.stringify(user_info || {})
    cached_user_info = user_info || {}
  }

  return true
}

let cached_user_info_str = null
let cached_user_info = null

const safeParse = (text) => {
  try {
    return JSON.parse(text)
  } catch (e) {
    return null
  }
}

/**
 * 如果你后续要支持“多个外部供应商”,推荐的扩展方式是:
 * 在 auth_user_info.js 里把 user_info 结构升级为 { provider, credential } 或者分 key 存(如 user_info_vendorA / user_info_vendorB ),
 * 然后让 getAuthHeadersFromUserInfo() 根据 provider 生成不同头——这样全项目只有一个地方需要知道供应商差异。
 */

/**
 * 从存储中获取用户信息
 * @param {*} options 选项对象,包含 storage 字段
 * @returns 如果用户信息存在且有效,则返回用户信息对象;否则返回 null
 */
export const getUserInfoFromStorage = (options = {}) => {
  const storage = Object.prototype.hasOwnProperty.call(options, 'storage') ? options.storage : globalThis.localStorage
  if (!storage || typeof storage.getItem !== 'function') {
    return null
  }

  const raw = storage.getItem('user_info')
  if (!raw) {
    if (storage === globalThis.localStorage) {
      cached_user_info_str = null
      cached_user_info = null
    }
    return null
  }

  if (storage === globalThis.localStorage && cached_user_info_str === raw && cached_user_info) {
    return cached_user_info
  }

  const parsed = safeParse(raw)
  if (!parsed || typeof parsed !== 'object') {
    if (storage === globalThis.localStorage) {
      cached_user_info_str = null
      cached_user_info = null
    }
    return null
  }

  if (storage === globalThis.localStorage) {
    cached_user_info_str = raw
    cached_user_info = parsed
  }

  return parsed
}

/**
 * 从存储中移除用户信息
 * @param {*} options 选项对象,包含 storage 字段
 */
export const removeUserInfoFromStorage = (options = {}) => {
  const storage = Object.prototype.hasOwnProperty.call(options, 'storage') ? options.storage : globalThis.localStorage
  if (storage && typeof storage.removeItem === 'function') {
    storage.removeItem('user_info')
  }
  if (storage === globalThis.localStorage) {
    cached_user_info_str = null
    cached_user_info = null
  }
}

/**
 * 从用户信息中提取认证头信息
 * @param {*} user_info 用户信息对象,包含 user_id 和 HTTP_USER_TOKEN 字段
 * @returns 如果用户信息有效,则返回包含 User-Id 和 User-Token 字段的对象;否则返回空对象
 */
export const getAuthHeadersFromUserInfo = (user_info) => {
  if (!user_info || typeof user_info !== 'object') {
    return {}
  }
  const user_id = user_info.user_id
  const user_token = user_info.HTTP_USER_TOKEN
  if (!user_id || !user_token) {
    return {}
  }
  return {
    'User-Id': user_id,
    'User-Token': user_token
  }
}