source

파이어베이스를 만들려고 시도하고 있습니다.auth().current 사용자 약속

goodcode 2022. 8. 24. 23:53
반응형

파이어베이스를 만들려고 시도하고 있습니다.auth().current 사용자 약속

사용자가 로그인 할 때 제한된 페이지로 전송하려고 합니다.그래서 사용자 오브젝트를 체크하여 경로를 보호하고 있습니다.문제는 사용자가 생성되거나 로그인 할 때 인증이 즉시 변경되지 않기 때문에 생성 또는 로그인 후firebase.auth().currentUser돌아올 수 있다null몇 밀리초 동안.그래서 페이지로 보내면 오류가 반환됩니다.

이것이 루트가 인증이 변경되었는지 확인하기 위해 잠시 대기하기 위해 시도하려고 합니다.코드에 문제가 있거나 더 나은 작성 방법이 없는지 궁금합니다.

P.S. 제가 확인할 수 있는 것은firebase.auth().onAuthStateChanged사용자 생성이나 로그인 시 어떻게 사용할 수 있는지 모르겠습니다.백그라운드에서만 실행되며 컨텍스트 없이 인증이 변경되었을 때 사용자에게 경로를 전송할 수 없습니다.타임아웃도 없습니다.

getUser( { commit } ) {
  return new Promise( ( resolve, reject )=> {
    let user, i = 0
    function checkForUser() {
      setTimeout( ()=> {
        i++
        user = firebase.auth().currentUser
        if ( user ) {
          router.push( { path: '/restricted' } )
          resolve()
        } else if ( i > 30 ) {
          reject( { message: 'Something went wrong, please try again.' } )
        } else {
          checkForUser()
        }
      }, 100 )
   }  
   checkForUser()
  } )
},

Firebase는 아직 https://github.com/firebase/firebase-js-sdk/issues/462에 대해 아무것도 하지 않았기 때문에 이는 긴 답변입니다.


Vuex에서 사용자를 동기화하는 방법은 다음과 같습니다.

두 개의 돌연변이와 편리한 게터가 있지만 특별한 건 없어요

state: {
  user: null
},
getters: {
  isAuthenticated: state => typeof state.user === 'object' && state.user !== null
},
mutations: {
  LOGIN: (state, user) => (state.user = user),
  LOGOUT: state => (state.user = null)
}

나는 가지고 있다firebase/index.js다음과 같은 Firebase 앱을 구성하는 파일

import firebase from 'firebase/app'
import 'firebase/auth'
// import any other Firebase libs like firestore, etc
import config from './config'
import store from '../store' // import the Vuex store

firebase.initializeApp(config)

export const auth = firebase.auth()
// export other Firebase bits like db, etc

const onAuthStateChangedPromise = new Promise((resolve, reject) => {
  auth.onAuthStateChanged(user => {
    store.commit(user !== null ? 'LOGIN' : 'LOGOUT', user)
    resolve(user)
  }, err => {
    reject(err)
  })
})

export const onAuthStateInit = () => onAuthStateChangedPromise

onAuthStateChanged리스너는 스토어를 사용자의 인증 상태와 동기화 상태로 유지하지만 외부 약속은 한 번만 해결됩니다(일관적인 콜).resolve()무시됩니다).이러한 약속의 특징으로 인해onAuthStateChangedPromise는 Firebase 인증 시스템이 초기화 단계를 완료했을 때를 검출하는 데 사용할 수 있습니다.

그리고 나서 그 약속을 공개했는데onAuthStateInit.

라우터에서는,meta명명된 플래그public루트가 퍼블릭접근 가능한지 여부를 판별합니다(대부분의 루트에는 인증이 필요합니다).

내 글로벌 내비게이션 가드는 이렇게 생겼다.

import { onAuthStateInit } from './firebase'

// define routes, new VueRouter, etc

router.beforeEach(async (to, from, next) => {
  await onAuthStateInit() // wait for auth system to initialise
  if (to.matched.every(route => route.meta.public) || store.getters.isAuthenticated) {
    next()
  } else {
    next({ name: 'sign-in' }) // redirect to sign-in page
  }
})

사용할 수 있습니다.await onAuthStateInit()첫 페이지 로드의 인증 초기화가 완료될 때까지 기다려야 하는 장소입니다.필요한 횟수만큼 호출할 수 있으며 한 번만 대기합니다.인증 초기화가 완료되면 이 약속은 즉시 해결됩니다.

★★★sign-in페이지는 다음 콜백이 정의된 Firebase Auth UI를 사용합니다.

import firebase from 'firebase/app'
import * as firebaseui from 'firebaseui'
import { auth } from '../firebase'
import 'firebaseui/dist/firebaseui.css'

const ui = new firebaseui.auth.AuthUI(auth)

export default {
  mounted () {
    // the ref is just a <div> in my template
    const container = this.$refs.firebaseuiAuthContainer
    ui.start(container, { 
      // signInOptions, etc
      callbacks: {
        signInSuccessWithAuthResult: authResult => {
          this.$router.push({ name: 'home' }) // go to homepage or wherever
        },
        signInFailure: err => {
          // handle sign-in error
        }
      }
    })    
  }
}

UI를 사용하다 ""에 됩니다.onAuthStateChange매뉴얼을 할 수 합니다.auth.SignInWith*()이치노

.signInWithRedirect 사용한 방법AuthProvidergetRedirectResultsyslog.Google:

firebase.auth().onAuthStateChanged(function(user) {
    if (user) {
        firebase.auth().getRedirectResult().then(function(result) {
            if (result.additionalUserInfo && result.additionalUserInfo.isNewUser) {
                // User just created.
            }
            if (result.user) {
                // User just signed in.
            }
        });
        // User is signed in.
    }
    else {
        // User is signed out.
        firebase.auth().signInWithRedirect(new firebase.auth.GoogleAuthProvider());
    }
});

상세정보 : https://firebase.google.com/docs/reference/js/firebase.auth.Auth#methods

언급URL : https://stackoverflow.com/questions/63047603/attempting-to-make-firebase-auth-currentuser-a-promise

반응형