React 및 Firebase를 사용한 인증

인증은 대부분의 공용 애플리케이션에 필요하고 구성하기가 어렵기 때문에 React와 Firebase로 인증하는 방법을 문서화하면 다른 사람들에게 도움이 될 것이라고 생각했습니다. 인증 절차가 변경되면 이 블로그를 업데이트하겠습니다. 또한 내 초기 전략은 h3webdevtut's tutorial 에서 파생됩니다.

이 가이드에서는 프로젝트용 웹 앱인 Firebase 프로젝트를 이미 만들고 React 프로젝트가 설정되어 있다고 가정합니다.

빠른 복사/붙여넣기를 위해 이 페이지의 맨 아래로 스크롤하십시오.

1. Firebase 설치



npm install firebase

2. firebaseConfig 추가


/src/fire.js 라는 파일을 만듭니다.

// firebaseConfig at /src/fire.js
import firebase from 'firebase'

const firebaseConfig = {
    apiKey: 'yourAPIKey',
    authDomain: 'yourAuthDomain',
    databaseURL: 'yourDatabaseURL',
    projectId: 'yourProjectId',
    storageBucket: 'yourStorageBucket',
    messagingSenderId: 'yourMessagingSenderId',
    appId: 'yourAppId'
}

const fire = firebase.initializeApp(firebaseConfig);

export default fire;


선택 사항(나중에 업데이트됨): firebaseConfig 변수를 .env 파일에 넣을 수 있습니다.

3. Firebase 콘솔에서 인증 방법 활성화



Firebase 콘솔에서 이메일 및 비밀번호 로그인 방법을 활성화합니다.

4. 가져오기, 상태 변수 만들기


/src/App.js(또는 앱이 있는 파일)에서 useStateuseEffect를 가져옵니다.

import React, { useState, useEffect } from 'react'
import fire from './fire'

사용자를 추적하기 위한 상태 추가:

const App () => {
    const [user, setUser] = useState('');
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [emailError, setEmailError] = useState('');
    const [passwordError, setPasswordError] = useState('');
    const [hasAccount, setHasAccount] = useState(false);

    ...
}


5. 이벤트를 처리하는 함수 생성



입력 및 오류를 지우는 두 가지 도우미 함수를 정의합니다.
clearInputs() :

const clearInputs = () => {
    setEmail('');
    setPassword('');
}

clearErrors() :

const clearErrors = () => {
    setEmailError('');
    setPasswordError('');
}

handleLogin() 사용자가 로그인할 때:

const handleLogin = () => {
    clearErrors();
    fire
        .auth()
        .signInWithEmailAndPassword(email, password)
        .catch(err => {
            // user firebase err code to determine kind of error
            // and handle it accordingly
            switch(err.code) {
                case "auth/invalid-email":
                case "auth/user-disabled":
                case "auth/user-not-found":
                    setEmailError(err.message);
                    break;
                case "auth/wrong-password":
                    setPasswordError(err.message);
                    break;
            }
        })
}

handleSignup() 사용자가 가입할 때:

const handleSignup = () => {
    clearErrors();
    fire
        .auth()
        .createUserWithEmailAndPassword(email, password)
        .catch(err => {
            // user firebase err code to determine kind of error
            // and handle it accordingly
            switch(err.code) {
                case "auth/email-already-in-use":
                case "auth/invalid-email":
                    setEmailError(err.message);
                    break;
                case "auth/weak-password":
                    setPasswordError(err.message);
                    break;
            }
        })
}

handleLogout() 사용자가 로그아웃할 때:

const handleLogout = () => {
    fire.auth().signOut();
}

authListener() 사용자 상태 업데이트:

const authListener = () => {
    fire.auth().onAuthStateChanged(user => {
        if (user) {
            clearInputs();
            setUser(user);
        } else {
            setUser('');
        }
    })
}


또한 authListener()useEffect()로 전화하십시오.

useEffect(() => {
    authListener();
}, [])


이 시점에서 /src/App.js는 다음과 같아야 합니다.

import React, { useState, useEffect } from 'react'
import fire from './fire'

const App () => {
    const [user, setUser] = useState('');
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [emailError, setEmailError] = useState('');
    const [passwordError, setPasswordError] = useState('');
    const [hasAccount, setHasAccount] = useState(false);

    const clearInputs = () => {
        setEmail('');
        setPassword('');
    }

    const clearErrors = () => {
        setEmailError('');
        setPasswordError('');
    }

    const handleLogin = () => {
        clearErrors();
        fire
            .auth()
            .signInWithEmailAndPassword(email, password)
            .catch(err => {
                // use firebase err code to determine kind of error
                // and handle it accordingly
                switch(err.code) {
                    case "auth/invalid-email":
                    case "auth/user-disabled":
                    case "auth/user-not-found":
                        setEmailError(err.message);
                        break;
                    case "auth/wrong-password":
                        setPasswordError(err.message);
                        break;
                }
            })
    }

    const handleSignup = () => {
        clearErrors();
        fire
            .auth()
            .createUserWithEmailAndPassword(email, password)
            .catch(err => {
                // use firebase err code to determine kind of error
                // and handle it accordingly
                switch(err.code) {
                    case "auth/email-already-in-use":
                    case "auth/invalid-email":
                        setEmailError(err.message);
                        break;
                    case "auth/weak-password":
                        setPasswordError(err.message);
                        break;
                }
            })
    }

    const handleLogout = () => {
        fire.auth().signOut();
    }

    const authListener = () => {
        fire.auth().onAuthStateChanged(user => {
            if (user) {
                clearInputs();
                setUser(user);
            } else {
                setUser('');
            }
        })
    }

    useEffect(() => {
        authListener();
    }, [])

    ...
}


6. 로그인 구성 요소 생성



로그인 페이지에 대한 구성 요소를 만듭니다. 예를 들어 /src/components/Login.js .

import React from 'react'

const Login = (props) => {
    const {
        email,
        setEmail,
        password,
        setPassword,
        handleLogin,
        handleSignup,
        hasAccount,
        setHasAccount,
        emailError,
        passwordError
    } = props;

    return (
        <section>
            <div>
                <label>Username</label>
                <input type="text" autoFocus required value={email} onChange={e => setEmail(e.target.value)}/>
                <p>{emailError}</p>
                <label>Password</label>
                <input type="text" required value={password} onChange={e => setPassword(e.target.value)}/>
                <p>{passwordError}</p>
                <div>
                    { hasAccount ? (
                        <>
                        <button onClick={() => handleLogin()}>Sign In</button>
                        <p>Don't have an account? <span onClick={setHasAccount(!hasAccount)}>Sign up</span></p>
                        </>
                    ) : (
                        <>
                        <button onClick={() => handleSignup()}>Sign Up</button>
                        <p>Already have an account? <span onClick={setHasAccount(!hasAccount)}>Sign in</span></p>
                        </>
                    )}
                </div>
            </div>
        </section>
    )
}

export default Login;


위의 구성 요소는 사용자 가입 및 로그인을 처리하는 데 필요한 베어본 코드입니다. 자신만의 스타일을 추가해야 합니다.

7. 앱에 로그인 구성 요소 추가


/src/App.js 에서 로그인 구성 요소를 가져옵니다.
./components/Login에서 로그인 가져오기

그리고 App 구성 요소에 대한 함수에서 사용자에 대해 조건부로 로그인 구성 요소를 반환합니다.

const App = () => {
    ...

    return (
        {hasAccount ? (
            <Login
            email={email}
            setEmail={setEmail}
            password={password}
            setPassword={setPassword}
            handleLogin={handleLogin}
            handleSignup={handleSignup}
            hasAccount={hasAccount}
            setHasAccount={setHasAccount}
            emailError={emailError}
            passwordError={passwordError}
            />
        ) : (

        )}
    )
}


8. 주의사항



이 튜토리얼은 (아직) 사용자 ID를 데이터베이스에 저장하는 방법을 포함하지 않으며 환영 이메일 및 비밀번호 분실 이메일을 처리하는 방법도 보여주지 않습니다. 시간이 있고 Firebase 인증을 더 잘 이해하기 때문에 앞으로 추가할 계획입니다.

이 블로그 게시물에서 오류를 발견하면 댓글을 남겨주시면 수정하겠습니다. 고맙습니다!

모든 코드



빠른 복사/붙여넣기를 위해.
/src/App.js
import React, { useState, useEffect } from 'react'
import fire from './fire'

const App () => {
    const [user, setUser] = useState('');
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [emailError, setEmailError] = useState('');
    const [passwordError, setPasswordError] = useState('');
    const [hasAccount, setHasAccount] = useState(false);

    const clearInputs = () => {
        setEmail('');
        setPassword('');
    }

    const clearErrors = () => {
        setEmailError('');
        setPasswordError('');
    }

    const handleLogin = () => {
        clearErrors();
        fire
            .auth()
            .signInWithEmailAndPassword(email, password)
            .catch(err => {
                // use firebase err code to determine kind of error
                // and handle it accordingly
                switch(err.code) {
                    case "auth/invalid-email":
                    case "auth/user-disabled":
                    case "auth/user-not-found":
                        setEmailError(err.message);
                        break;
                    case "auth/wrong-password":
                        setPasswordError(err.message);
                        break;
                }
            })
    }

    const handleSignup = () => {
        clearErrors();
        fire
            .auth()
            .createUserWithEmailAndPassword(email, password)
            .catch(err => {
                // use firebase err code to determine kind of error
                // and handle it accordingly
                switch(err.code) {
                    case "auth/email-already-in-use":
                    case "auth/invalid-email":
                        setEmailError(err.message);
                        break;
                    case "auth/weak-password":
                        setPasswordError(err.message);
                        break;
                }
            })
    }

    const handleLogout = () => {
        fire.auth().signOut();
    }

    const authListener() => {
        fire.auth().onAuthStateChanged(user => {
            if (user) {
                clearInputs();
                setUser(user);
            } else {
                setUser('');
            }
        })
    }

    useEffect(() => {
        authListener();
    }, [])

    return (
        {hasAccount ? (
            <Login
            email={email}
            setEmail={setEmail}
            password={password}
            setPassword={setPassword}
            handleLogin={handleLogin}
            handleSignup={handleSignup}
            hasAccount={hasAccount}
            setHasAccount={setHasAccount}
            emailError={emailError}
            passwordError={passwordError}
            />
        ) : (

        )}
    )
}

/src/components/Login.js
import React from 'react'

const Login = (props) => {
    const {
        email,
        setEmail,
        password,
        setPassword,
        handleLogin,
        handleSignup,
        hasAccount,
        setHasAccount,
        emailError,
        passwordError
    } = props;

    return (
        <section>
            <div>
                <label>Username</label>
                <input type="text" autoFocus required value={email} onChange={e => setEmail(e.target.value)}/>
                <p>{emailError}</p>
                <label>Password</label>
                <input type="text" required value={password} onChange={e => setPassword(e.target.value)}/>
                <p>{passwordError}</p>
                <div>
                    { hasAccount ? (
                        <>
                        <button onClick={() => handleLogin()}>Sign In</button>
                        <p>Don't have an account? <span onClick={setHasAccount(!hasAccount)}>Sign up</span></p>
                        </>
                    ) : (
                        <>
                        <button onClick={() => handleSignup()}>Sign Up</button>
                        <p>Already have an account? <span onClick={setHasAccount(!hasAccount)}>Sign in</span></p>
                        </>
                    )}
                </div>
            </div>
        </section>
    )
}

export default Login;




좋은 웹페이지 즐겨찾기