IT이야기

Firebase 인증 상태가 변경된 후 Vue 앱 초기화

cyworld 2022. 5. 25. 22:19
반응형

Firebase 인증 상태가 변경된 후 Vue 앱 초기화

나는 내 Vue/vuex/vue-router + Firebase 앱에 약간의 문제가 있다.부트스트랩 코드는 Firebase와 Vuex에서 로그인한 사용자(있는 경우):

new Vue({
  el: '#app', router, store, template: '<App/>', components: { App },
  beforeCreate() {
    firebase.initializeApp(firebaseConfig)
      // Because the code below is async, the app gets created before user is returned...
      .auth().onAuthStateChanged(user => {
        this.$store.commit('syncAuthUser', user) // this executes too late...
      })
  }
})

내 경로에, 나는

{ path: '/home', name: 'Home', component: Home, meta: { requiresAuth: true } }

게다가

router.beforeEach((to, from, next) => {
  let authUser = store.getters.authUser // this is not set just yet...

  if (to.matched.some(record => record.meta.requiresAuth)) {
    if (!authUser) {
      next('signin') // /home will always hit here...
    }
    next()
  }
  else {
    next()
  }
})

문제

댓글에 언급된 바와 같이, 앱은 인증된 사용자를 너무 늦게 받는다.그래서, 당신이 갈때/home로그인하는 동안 앱은beforeEach노선에 입항하다...그리고 사용자 인스턴스는 아직 사용할 수 없기 때문에 실제로 로그인되어 있지 않은 것으로 생각할 것이다(몇 분 후에 적절하게 업데이트되는 내 계산된 속성에서 명확함).

질문

그렇다면, 어떻게 코드를 변경하면 Firebase가 사용자를 반환하고 해당 사용자가 Vuex 스토어에 전달된 후에만 Vue 앱이 초기화될 수 있는가?내가 완전히 잘못하고 있다면 알려 줘.

시도

  1. 나는 "구독 취소" 접근법을 시도했다. 그러나, 그것의 문제는 그 접근법이onAuthStateChanged한 번만 트리거할 수 있을 겁니다.그래서, 만약 내가 내 결정권을 가지고 있다면this.$store.commit('syncAuthUser', user)그러면 그 코드는 앱이 만들어졌을 때만 실행되며, 예를 들어 사용자가 로그아웃할 때는 실행되지 않는다.
  2. 또한 여기서 더 나은 접근을 시도했다.나는 나를 위해 일했지만, 나는 포장하는 것을 기분 나쁘게 느꼈다.onAuthStateChanged다른 곳에Promise확실히 더 나은 방법이 있을 것이다. 게다가, 인증 사용자 초기화 로그인을 경로 파일에 배치하는 것은 잘못된 것 같다.

가장 쉬운 방법은 앱을 마운트하기 전에 인증 상태를 기다리는 것이다.

const app = new Vue({
  router,
  store,
  render: h => h(App),
});

firebase.auth().onAuthStateChanged(user => {
  store.commit('authStateChanged', user);
  app.$mount('#app');
});

장착하기 전에 스피너를 보여 주고 싶다면#app:

<div id="app"><div class="loader">Loading...</div></div>

사실, 당신이 auth state 로직을 추출하면 당신의 행동이 더 깨끗해지고 앱이 더 신뢰할 수 있게 될 것이다.authStateChanged위와 같이 커밋하고 여기서 경로 리디렉션을 처리하십시오.이렇게 하면 경로에 있는 동안 인증 상태가 변경될 경우 처리됨router.beforeEach네가 언제 갈지 확인할 거야

firebase.auth().onAuthStateChanged(user => {
  store.commit('auth/authStateChanged', user);

  const isAuthed = Boolean(user);
  const { meta } = router.history.current;

  if (isAuthed && meta.isPublicOnly) { // e.g. /login + /signup
    router.push('/dashboard');
  } else if (!isAuthed && meta.isPrivate) {
    router.push('/login');
  }

  app.$mount('#app');
});

첫째,router.beforeEach콜백은 이 전에 발생하므로 인증 상태가 결정될 때까지 콜백은 무시하십시오.첫 번째 리디렉션을 처리하므로onAuthStateChanged그건 중요하지 않아.

state: {
  isInited: false,
  isAuthed: false,
},
mutations: {
  authStateChanged(state, user) {
    state.isAuthed = Boolean(user);
    state.isInited = true;
  }
}

router.beforeEach((to, from, next) => {
  const { isInited, isAuthed } = store.state.user;

  if (isInited) {
    if (!isAuthed && to.matched.some(record => record.meta.isPrivate)) {
      return next('/login');
    } else if (isAuthed && to.matched.some(record => record.meta.isPublicOnly)) {
      return next('/dashboard');
    }
  }

  next();
});

당신은 아마도 경로 로딩이 될 때까지 전혀 막을 수 있을 것이다.isInited대안으로 진실이다.

./App.vue

created: function() {
  auth.onAuthStateChanged(user => {

    this.$store.dispatch("SET_USER", user)

    user.getIdToken().then( token => {
      this.$store.dispatch("SET_TOKEN", token)
    })
}

./store.js(주문)

export default {
  SET_USER(state, user) {
    state.authenticated = !!user
    state.user = {
      email: user ? user.email : null,
      displayName: user ? user.displayName : null,
      photoURL: user ? user.photoURL : null,
    }
  }
  SET_TOKEN(state, payload) {
    state.token = payload
  }
}

개요

라이프사이클

이 예제는 Vue를 사용하여 작동한다.created:라이프사이클 훅안쪽에created:우리는 사용한다.auth.onAuthStateChanged이벤트 청취기를 돌리기 위해.당신의 앱은 현재 소방서에서 인증 변경을 수신하고 있다.

auth.onAuthStateChanged(user => { ...listening for user objects... })

userFirebase가 인증 상태 변경을 발견할 때마다 객체가 반환된다.인증 및 인증에 해당 속성방법을 사용하십시오.

속성: user.emailVerfied

방법: user.getIdToken()

TL;DR

Firebase 사 시onAuthStateChanged, 실행해야 한다.Observable, 그리고Subscriptions물건들RxJS 관측 가능은 비동기적임promiseFirebase의 인증 응답을 기다리는 데 도움이 될 겁니다.

번째 주장을 보시오.nextOrObserver설명서에서 다음을 참조하십시오.

onAuthStateChanged(nextOrObserver, error, completed) returns function()

관측 가능한 설계 패턴(즉, 비동기, 푸시, 멀티캐스트)은 여기에 기록되어 있다.

참조URL: https://stackoverflow.com/questions/45204288/initialize-vue-app-after-firebase-auth-state-changed

반응형