gpt4 book ai didi

firebase - NuxtJS 状态更改和 firebase 身份验证

转载 作者:行者123 更新时间:2023-12-05 06:19:06 26 4
gpt4 key购买 nike

本人还是nuxt初学者,如有不妥之处还请见谅

我正在为 nuxt 使用“官方”firebase 模块 https://firebase.nuxtjs.org/访问 Firebase 服务,例如 auth signIn 和 singOut。

这有效。

但是,我在通用模式下使用 nuxt,我无法在我的页面获取功能中访问它。所以我的解决方案是将此信息保存在 vuex 存储中并在它发生变化时更新它。

因此,一旦用户登录或 firebase 身份验证状态发生变化,vuex 存储中就需要发生状态变化。

目前,当用户登录或 firebase 身份验证状态更改时,如果用户仍处于登录状态,我会像这样将状态保存到我的商店:

const actions = {
async onAuthStateChangedAction(state, { authUser, claims }) {
if (!authUser) {
// claims = null
// TODO: perform logout operations
} else {
// Do something with the authUser and the claims object...
const { uid, email } = authUser
const token = await authUser.getIdToken()

commit('SET_USER', { uid, email, token })
}
}
}

我还有一个设置状态的突变,一个获取状态的 getter 和实际状态对象以及存储初始状态:

const mutations = {
SET_USER(state, user) {
state.user = user
}
}

const state = () => ({
user: null
})

const getters = {
getUser(state) {
return state.user
}
}

我的问题是,在我的许多页面上,我使用 fetch 方法从 API 获取数据,然后将这些数据存储在我的 vuex 存储中。

此获取方法使用 axios 进行 api 调用,如下所示:

async fetch({ store }) {
const token = store.getters['getUser'] //This is null for a few seconds
const tempData = await axios
.post(
my_api_url,
{
my_post_body
},
{
headers: {
'Content-Type': 'application/json',
Authorization: token
}
}
)
.then((res) => {
return res.data
})
.catch((err) => {
return {
error: err
}
console.log('error', err)
})
store.commit('my_model/setData', tempData)
}

Axios 需要我的 firebase 用户 ID token 作为发送到 API 的 header 的一部分以进行授权。

当 fetch 方法运行时,状态并不总是改变或更新,因此在状态改变之前用户的状态仍然为 null,这通常是大约一秒钟之后,这对我来说是个问题因为我需要商店中的 token 才能进行 API 调用。

在我的 fetch 方法中调用 axios api 之前,如何等待 store.user 状态完成更新/不为空?

我考虑过在用户登录时使用 cookie 来存储此信息。然后,在 fetch 方法中,我可以使用 cookie 来获取 token ,而不必等待状态更改。我使用这种方法的问题是 cookie 在更新其 token 之前还需要等待状态更改,这意味着它将在初始页面加载时使用旧 token 。我可能仍会选择此解决方案,只是感觉这是处理此问题的错误方法。有没有更好的方法来处理此类难题?

此外,当在 fetch 中时,第一次加载将从服务器进行,​​因此我可以从 cookie 中获取 token ,但是下一次加载将从客户端进行,所以如果存储,我该如何检索 token 加载时值仍然为空?

编辑:

我选择了 SPA 模式。经过长时间的深思熟虑,我真的不需要 nuxt 服务器,而且 SPA 模式具有“类似服务器”的行为,您仍然可以在页面呈现之前使用 asyncdata 和 fetch 来获取数据,中间件仍然工作类似,实际上是身份验证在不需要保持客户端和服务器与访问 token 等同步的情况下工作。我仍然希望在未来看到更好的解决方案,但现在 SPA 模式工作正常。

最佳答案

我在寻找类似问题的解决方案时遇到了这个问题。在回答这个问题之前,我有一个与其他答案中提到的类似的解决方案,我正在寻找的是实现细节。

我使用 nuxt.js,我想到的第一个方法是制作一个 layout组件并渲染 <Nuxt/>仅当用户通过身份验证时才执行指令,但通过这种方法,我只能拥有一个布局文件,如果我有多个布局文件,我将不得不在每个布局中实现相同的预授权机制,尽管这是可行的- 像现在一样我不是在每个页面中实现它,而是在每个布局中实现它应该少得多。

我找到了一个更好的解决方案,那就是使用 middlewares 在 nuxt 中,您可以返回一个 promise 或使用 async-await 和中间件来停止应用程序安装过程,直到该 promise 得到解决。这是示例代码:

// middleware/auth.js
export default async function ({ store, redirect, $axios, app }) {
if (!store.state.auth) { // if use is not authenticated
if (!localStorage.getItem("token")) // if token is not set then just redirect the user to login page
return redirect(app.localePath('/login'))
try {
const token = localStorage.getItem("token");
const res = await $axios.$get("/auth/validate", { // you can use your firebase auth mechanism code here
headers: {
'Authorization': `Bearer ${token}`
}
});
store.commit('login', { token, user: res.user }); // now just dispatch a login action to vuex store
}
catch (err) {
store.commit('logout'); // preauth failed, so dispatch logout action which will clear localStorage and our Store
return redirect(app.localePath('/login'))
}
}
}

现在您可以在您的页面/布局组件中使用这个中间件,如下所示:

<template>
...
</template>
<script>
export default {
middleware: "auth",
...
}
</script>

关于firebase - NuxtJS 状态更改和 firebase 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60971705/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com