【问题标题】:Firebase/Nuxt module with Vuex store data with auth middleware: Why is user object shown as null?带有 Vuex 的 Firebase/Nuxt 模块使用身份验证中间件存储数据:为什么用户对象显示为空?
【发布时间】:2021-05-03 17:45:22
【问题描述】:

我也有类似的问题:https://github.com/nuxt-community/firebase-module/issues/252

但是,我尝试了建议的解决方案,但不确定是否正确,因此在此处发布以寻求帮助:

这是我的问题:使用中间件时,如果我尝试直接访问页面(例如输入 URL 与导航到该页面),用户存储对象将返回为 null

导航没有问题,但问题在于通过在浏览器窗口中输入 URL 或硬刷新直接访问页面。 我的用例是试图阻止已登录的用户访问登录页面(或注册页面),因此我想我会写一个这样的中间件,但控制台记录它显示用户是 null 在直接页面访问和硬刷新。

middleware/auth

export default function ({ app, store, redirect }) {
  console.log('user?', store.state.user.currentUser)
}

我关注了Auth SSR tutorial,但也许我在某处犯了错误。有人可以帮我正确配置吗?

nuxt.config.js:

export default {
  vue: {
    config: {
      productionTip: false,
      devtools: true
    }
  },
  publicRuntimeConfig: {
    baseURL: process.env.BASE_URL || 'http://localhost:3000'
  },
  privateRuntimeConfig: {},
  head: {
    htmlAttrs: {
      lang: 'en'
    },
    title: 'pixstery',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' }
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
  },

  // Global CSS (https://go.nuxtjs.dev/config-css)
  css: [],

  // Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
  plugins: [
    // {
    //   src: '~/plugins/vuex-persist',
    //   mode: 'client'
    // }
  ],

  // Auto import components (https://go.nuxtjs.dev/config-components)
  components: true,

  // Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)
  buildModules: [
    // https://go.nuxtjs.dev/eslint
    '@nuxtjs/eslint-module',
    // https://go.nuxtjs.dev/tailwindcss
    '@nuxtjs/tailwindcss',
    '@nuxtjs/html-validator'
  ],

  // Modules (https://go.nuxtjs.dev/config-modules)
  modules: ['@nuxtjs/pwa', '@nuxtjs/firebase', '@nuxt/content'],
  firebase: {
    config: {
      apiKey: 'AIzaSyD4ge8g6oe0xp6vQ1y85AbvI8PXcDKzoKk',
      authDomain: 'xxx.firebaseapp.com',
      databaseURL: '<databaseURL>',
      projectId: 'xxx',
      storageBucket: 'xxx.appspot.com',
      messagingSenderId: '471446831599',
      appId: '1:471446831599:web:16ec77402cbb336f67b61a',
      measurementId: 'G-XFVH7QFG4L' // optional
    },
    services: {
      auth: {
        persistence: 'local', // default
        initialize: {
          onAuthStateChangedAction: 'user/onAuthStateChangedAction',
          subscribeManually: false
        },
        ssr: true
        // emulatorPort: 9099,
        // emulatorHost: 'http://localhost'
      },
      firestore: {
        chunkName:
          process.env.NODE_ENV !== 'production' ? 'firebase-auth' : '[id]', // default
        enablePersistence: true
        // emulatorPort: 8080,
        // emulatorHost: 'localhost'
      },
      functions: {
        location: 'us-central1'
        // emulatorPort: 12345,
        // emulatorHost: 'http://10.10.10.3'
      },
      storage: true
    }
  },
  pwa: {
    // disable the modules you don't need
    meta: false,
    icon: false,
    // if you omit a module key form configuration sensible defaults will be applied
    // manifest: false,

    workbox: {
      importScripts: [
        // ...
        '/firebase-auth-sw.js'
      ],
      // by default the workbox module will not install the service worker in dev environment to avoid conflicts with HMR
      // only set this true for testing and remember to always clear your browser cache in development
      // dev: process.env.NODE_ENV === 'development'
      dev: true
    }
  },

  // Content module configuration (https://go.nuxtjs.dev/config-content)
  content: {},

  // Build Configuration (https://go.nuxtjs.dev/config-build)
  build: {},
  router: {
    middleware: ['auth']
  }
}

store/user:

  async nuxtServerInit({ dispatch, commit }, { res }) {
    if (res && res.locals && res.locals.user) {
      const { allClaims: claims, idToken: token, ...authUser } = res.locals.user

      await dispatch('onAuthStateChangedAction', {
        authUser,
        claims,
        token
      })
    }
  },
  async onAuthStateChangedAction({ commit, dispatch }, { authUser, claims }) {
    console.log('auth state changed....')
    console.log('authUser: ', authUser)
    console.log('claims: ', claims)

    try {
      if (!authUser) {
        await dispatch('logOutUser')
        return
      } else if (authUser && authUser.emailVerified) {
        const {
          uid,
          email,
          emailVerified,
          displayName = '',
          photoURL,
          metadata,
          providerData,
          providerId,
          tenantId
        } = authUser
        commit('SET_AUTH_USER', {
          uid,
          email,
          emailVerified,
          displayName,
          photoURL, // results in photoURL being undefined for server auth
          metadata,
          providerData,
          providerId,
          tenantId,
          isAdmin: claims.custom_claim // use custom claims to control access (see https://firebase.google.com/docs/auth/admin/custom-claims)
        })
        console.log('fetching profile...')
        await dispatch('getUserProfile', authUser)
      } else {
        console.log('User logged out or not verified')
        return
      }
    } catch (error) {
      console.error('Error with Auth State observer: ', error)
    }
  },

因此,使用上面的代码,我的login 页面(当用户已经登录时)的硬刷新(或通过浏览器 URL 直接导航)会在控制台中显示这一点(注意 user?, null 来自中间件)

感谢您的帮助!

【问题讨论】:

  • 您可能希望从该帖子 (firebase.config) 中删除敏感数据或将其更改为伪造的。
  • 感谢您的提醒!发帖是安全的。看到这个:stackoverflow.com/questions/37482366/…
  • 有道理。感谢您的链接。

标签: firebase nuxt.js vuex


【解决方案1】:

问题可能有两个来源:

  1. 尝试将您的 nuxtServerInit 操作移至 store/index.js

目前,store/user.js 中有 nuxtServerInit,这意味着实际操作的命名空间为 user/nuxtServerInit。因此它没有被调用。

  1. 你提到了硬重装。在硬重载期间,Service Worker 被绕过,因此它不会将身份验证令牌传递给服务器端。见here

【讨论】:

  • 谢谢。自从我发布原始帖子以来已经有更新......我确实将 nuxtServerInit 移动到根存储 index.js,而不是命名空间。然而,这并没有解决问题。至于你的第二点,这看起来很有趣......我将不得不更详细地查看它。谢谢!
  • 我要克隆这个 repo 看看我是否遇到同样的问题:github.com/nuxt-community/firebase-module/issues/…
猜你喜欢
  • 2023-03-09
  • 2019-02-27
  • 2021-08-26
  • 2018-09-30
  • 2019-02-26
  • 1970-01-01
  • 2021-09-15
  • 2021-04-05
相关资源
最近更新 更多