Nuxt新手-Firebase身份验证无法进行刷新

时间:2019-12-22 21:02:12

标签: javascript firebase vue.js nuxt.js

我已经搜索并尝试了很多示例和不同的东西,但仍然完全停留在这里-我已经为此花了2天了…… 我遇到一个常见问题,如果我登录并单击链接,我的应用程序可以正常运行,但是如果我在浏览器中刷新或直接点击URL,Firebase似乎认为我没有经过身份验证的会话。

  

编辑因此,在想了更多之后,我认为之所以会这样,是因为刷新后,Vue 服务器 请求。点击链接后, 客户端 发出请求...最大的不同是服务器请求上未设置会话或未发送cookie。   引发重定向的解决方案吗?还是有一种在页面加载时发送浏览器的cookie /会话的方法?还是在Vue和Firebase之间建立某种服务器到服务器的身份验证,然后通过Vue / Vuex管理登录状态?

这是FB返回的错误:

Error during getting LIST of presentations! FirebaseError: [code=permission-denied]: Missing or insufficient permissions. 

这是我在做什么:

首先,在我的store / index.js中,我们解码用户数据的cookie并将其分派到名为setUserLoggedIn的操作(我知道我两次设置了相同的值,但是保留了它的完整性:))

此代码似乎可以按预期工作(即始终在Nuxt启动时执行。我们这样做是为了确保在执行任何操作之前,我们已将Cookie中的用户数据保存在Vuex存储中)。它将cookie解码/将期望值发送到setUserLoggedin

    import { getUserFromCookie } from '@/helpers'
export const actions = {
  async nuxtServerInit({ dispatch }, { req }) {
    const user = getUserFromCookie(req)
    console.log('This code fires first with user ' + JSON.stringify(user))
    if (user) {
      console.log('Found a user cookie - maybe we can log them in')
      await dispatch('user/setUserLoggedin', {
        email: user.email,
        uid: user.user_id,
        thisUserid: user.user_id
      })
    }
  }
}

然后,我们通过两次更改将登录状态和用户详细信息提交回Vuex状态,然后确认用户已使用Firebase登录这一事实:

 setUserLoggedin({ commit }, user) {

    commit('LOGIN_STATUS', true)
    console.log(`Re-affirming login user object is ${JSON.stringify(user)}`)
    commit('LOGIN_USER', {
      loginInstanceId: 'a-key-to-track-each-login-session',
      useruniqueid: user.thisUserid,
      emailaddress: user.email,
      uid: user.thisUserid
    })
    return UserService.affirmLogin(user)
  },

最后,我尝试检查是否与Firebase进行了会话(firebase.auth()。currentUser返回未定义)。使用其他Firebase命令侦听状态更改或类似的操作都没有运气。从字面上看,我尝试过的所有操作都会产生空白。

  async affirmLogin(myuser) {
    const currentUser = await firebase.auth().currentUser
    console.table(currentUser)
  },

我还设置了一个带有Firebase令牌的令牌

await firebase
        .auth()
        .signInWithEmailAndPassword(user.emailaddress, user.password)
        .then(() => {
          firebase.auth().onAuthStateChanged(user => {
            currentUser = user.uid
          })
        })
      const token = await firebase.auth().currentUser.getIdToken(true)
      Cookies.set('access_token', token) // saving token in cookie for server rendering

我已经尝试了一百万种不同的方法-从配置Vuex状态/吸气剂和Firebase命令,到注释掉我的代码的生命,调试等等,但是我无法弄清楚为什么这不起作用。即使我有一个cookie并且我认为Vuex存储中的数据,Firebase似乎还是忽略或看不到任何现有的刷新会话。

但是,如果我创建了一个通过UI导航到的页面,请按上面的路线进行操作(即,使表单提交按钮按affirmLogin)。

我认为问题是我的会话不正确,但是我看不出它可能是什么。我也不确定Firebase应该如何在刷新时收集用户ID。我见过的其他示例似乎有它的“作用”,但对我而言却不是:(任何帮助,不胜感激!

谢谢

2 个答案:

答案 0 :(得分:0)

TBH我不了解Vue,Nuxt, Firebase,但我的第一个猜测是,在您要求Firebase返回 currentUser 的那一刻,尚未完全初始化或类似的东西。 Firebase文档似乎同意:

  

注意:currentUser 也可能为null,因为auth对象尚未完成初始化。如果您使用观察者来跟踪用户的登录状态,则无需处理这种情况。

您是否尝试过使用身份验证状态观察器?看起来像这样:

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
  } else {
    // No user is signed in.
  }
});

我建议您尽早在代码中进行设置,以确保您不会错过身份验证状态更改。您可以从这样的内容开始:

setUserLoggedin({ commit }, user) {
  const userPromise = new Promise((resolve, reject) => {
    firebase.auth().onAuthStateChanged(function(user) {
      if (user) {
        // User is signed in.
        console.log('got user', user);
        resolve(true);
      } else {
        // No user is signed in.
        resolve(false);
      }
    });
  });

  commit('LOGIN_STATUS', true);

  console.log(`Re-affirming login user object is ${JSON.stringify(user)}`);
  commit('LOGIN_USER', {
    loginInstanceId: 'a-key-to-track-each-login-session',
    useruniqueid: user.thisUserid,
    emailaddress: user.email,
    uid: user.thisUserid,
  });

  return userPromise;
}

我很确定这作为最终解决方案还不够好,但是如果我的猜测是正确的,它可能会帮助您走上正确的轨道。

答案 1 :(得分:0)

我有相同的问题,刷新或重新加载后收到未经身份验证的错误,问题来自用户端点的propertyName,如果直接返回用户而不是对象'user':{...},则应放置{{1} },在nuxt config的auth选项中,您可以通过直接执行此代码来检查auth将收到什么结果

propertyName : false