21.10.19 ๊ณต๋ถ€๊ธฐ๋ก๐Ÿง‘โ€๐Ÿ’ป

devduckยท2021๋…„ 10์›” 19์ผ
0
post-thumbnail

FireBase, React๋ฅผ ํ™œ์šฉํ•œ ํŠธ์œ„ํ„ฐ ํด๋ก ์ฝ”๋”ฉ๐Ÿง‘โ€๐Ÿ’ป


์˜ค๋Š˜ ์™„๋ฃŒํ•œ ๋ชฉ๋ก
1. ๋กœ๊ทธ์ธ ๊ตฌํ˜„๊ธฐ๋Šฅ
2. ์†Œ์…œ๋กœ๊ทธ์ธ (Github, Google)
3. ๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ


๋ฐฑ์—”๋“œ ํŒŒํŠธ๋ฅผ ํŒŒ์ด์–ด๋ฒ ์ด์Šค๋ฅผ ํ™œ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํŒŒ์ด์–ด๋ฒ ์ด์Šค ์‚ฌ์ดํŠธ๋ฅผ ์ฐธ๊ณ ํ–ˆ๋‹ค.
https://firebase.google.com/docs/auth/web/firebaseui?hl=ko

1. ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ

์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•ด useState ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ–ˆ๋‹ค.

    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");
    const [newAccount, setnewAccount] = useState(true);
    const [error, setError] = useState("");

๋กœ๊ทธ์ธ์„ ์ง€์†ํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•

ํŒŒ์ด์–ด๋ฒ ์ด์Šค์—์„œ ๋กœ๊ทธ์ธ์„ ์ง€์†ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” setPersistence๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
setPersistence๋Š” local, session, none์˜ต์…˜์„ ๊ฐ–๊ณ  ์žˆ๋‹ค.

  • local : ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ข…๋ฃŒํ•ด๋„ ๋กœ๊ทธ์ธ ์œ ์ง€
    Local ์˜ต์…˜์€ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ข…๋ฃŒํ•ด๋„ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ๊ธฐ์–ตํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.

  • session : ์›น ๋ธŒ๋ผ์šฐ์ €์˜ ํƒญ์„ ์ข…๋ฃŒํ•˜๋ฉด ๋กœ๊ทธ์•„์›ƒ

  • none : ์ƒˆ๋กœ๊ณ ์นจํ•˜๋ฉด ๋กœ๊ทธ์•„์›ƒ

    ํ•˜์ง€๋งŒ ๊ธฐ๋ณธ๊ฐ’์€ local๋กœ ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๋”ฐ๋กœ ์„ค์ •ํ•  ํ•„์š”์—†์ด ์ง„ํ–‰ํ–ˆ๋‹ค.

2. ์†Œ์…œ ๋กœ๊ทธ์ธ


<div>
    <button name="Google" onClick ={onSocialClick} >Continue with Google</button>
    <button name="Github" onClick ={onSocialClick} >Continue with Github</button>
</div>

const onSocialClick =  async (event) =>{
     const {target:{name},
    } = event;
    let provider;
    if(name === "Google"){
        provider = new GoogleAuthProvider();
    }else if(name === "Github"){
        provider = new GoogleAuthProvider();
    }
    await signInWithPopup(auth, provider);
 };

๋จผ์ € ๊ตฌ๊ธ€๊ณผ ๊นƒํ—ˆ๋ธŒ ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธํ•˜๊ธฐ ์œ„ํ•ด ํŒŒ์ด์–ด๋ฒ ์ด์Šค์—์„œ๋Š”

GoogleAuthProvider์™€ GithubAuthProvider๋ฅผ ์ด์šฉํ•œ๋‹ค.
๋˜ํ•œ signInWithPopupํ•จ์ˆ˜๊ฐ€ ๋น„๋™๊ธฐ ์ž‘์—…์ด๊ธฐ ๋•Œ๋ฌธ์— async-await๋ฌธ์„ ์‚ฌ์šฉํ–ˆ๋‹ค.
provider์„ signInWithPopup ํ•จ์ˆ˜ ์ธ์ž๋กœ ๋„˜๊ฒจ ๋กœ๊ทธ์ธ์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

๊ฒฐ๊ณผ

3. ๋กœ๊ทธ์•„์›ƒ

๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ์„ ๋ฒ„ํŠผ์„ ์ด์šฉํ•˜์—ฌ ํ•˜๊ธฐ ์œ„ํ•ด ๋„ค๋น„๊ฒŒ์ด์…˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

const Navigation = () => 
<nav>
    <ul>
    <li>
        <Link to ="/">Home</Link>
    </li>
    <li>
        <Link to ="/profile">Profile</Link>
    </li>
    </ul>
 </nav>

Profile์„ ํด๋ฆญํ•˜๋ฉด /profile๋กœ ์ด๋™ํ•˜๊ฒŒ ๋ผ์šฐํ„ฐ์— ์ถ”๊ฐ€ํ–ˆ๋‹ค.

const Profile = () => <span>Profile</span>

export default () => {
    const onLogOutClick = () => auth.signOut();
    return (
    <>
    <button onClick ={onLogOutClick}>Log out</button>
    </>
    );
};
import { auth } from 'fbase';

const Profile = () => <span>Profile</span>

export default () => {
    const onLogOutClick = () => auth.signOut();
    return (
    <>
    <button onClick ={onLogOutClick}>Log out</button>
    </>
    );
};

ํŒŒ์ด์–ด๋ฒ ์ด์Šค์—์„œ ๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” signOut()ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— onLogoutClick ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ , ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด signOutํ•จ์ˆ˜๊ฐ€ ๋ฐœ๋™๋˜๊ฒŒ ์ฝ”๋“œ๋ฅผ ์งฐ๋‹ค.

ํ•˜์ง€๋งŒ ๋กœ๊ทธ์•„์›ƒ์„ ํ•ด๋„ ์—ฌ์ „ํžˆ Profile ์‚ฌ์ดํŠธ์— ์œ„์น˜ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—,
Redirect๋ฅผ ๋ฐฐ์น˜ํ–ˆ๋‹ค.


const AppRouter = ({isLoggedIn}) =>{ //Router์„ ์ด๋ฏธ ์ •์˜ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ์ •์˜
    //์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ ํ”„๋กญ์Šค๋Š” ๊ตฌ์กฐ๋ถ„ํ•ด ํ• ๋‹น์œผ๋กœ ์‚ฌ์šฉ
   
    return( // switch๋ฅผ ์ด์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ผ์šฐํŠธ ์ค‘ ํ•˜๋‚˜๋งŒ ๋ Œ๋”๋งํ•˜๊ฒŒ ํ•ด์คŒ.
        <Router>
            {isLoggedIn &&<Navigation />} 
            {/* && -> ๋กœ๊ทธ์ธ์ด ๋งž๋‹ค๋ฉด Navigation => true*/}
            <Switch>  
                {isLoggedIn ?( // ๋กœ๊ทธ์ธ ์ƒํƒœ ์‹œ
                <>
                    <Route exact path ="/">  
                        <Home />
                    </Route>  
                    <Route exact path ="/profile">  
                    <Profile />
                </Route>
                <Redirect from="*" to="/" />
                </> 
                ) : ( // ๋น„๋กœ๊ทธ์ธ ์ƒํƒœ ์‹œ
                    <>
                    <Route exact path ="/"> 
                        <Auth />
                    </Route>   
                    <Redirect from="*" to="/" />
                    </>
                )}
            </Switch>
        </Router>
    )
}

์ž์„ธํžˆ ์„ค๋ช…ํ•˜์ž๋ฉด switch๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•œ ๊ฐ€์ง€ ๋ผ์šฐํŠธ๋งŒ ๋ Œ๋”๋งํ•˜๊ฒŒ ํ•ด์ฃผ๋Š”๋ฐ,
isLoggedIn์˜ ์ƒํƒœ๋ฅผ ๋ณด๊ณ  ๋กœ๊ทธ์ธ์ด ์œ ๋ฌด๋ฅผ ํŒ๋‹จํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ์— ๋”ฐ๋ฅธ ๋ผ์šฐํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ฒŒ ํ•ด์คฌ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ๋กœ๊ทธ์•„์›ƒ์ด ๋˜๋ฉด isLoggedIn์ด false๋กœ ๋ฐ”๋€Œ๊ธฐ ๋•Œ๋ฌธ์—
false๋กœ ๋ถ„๊ธฐํ•˜๋Š” ๋ผ์šฐํŠธ๊ฐ€ ๋™์ž‘ํ•ด์•ผํ•˜์ง€๋งŒ, exact path ="/"๋Š” ์ •ํ™•ํžˆ ์ฃผ์†Œ๊ฐ€ "/"์ธ ๊ฒฝ์šฐ์—๋งŒ ํ•ด๋‹น๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๋กœ๊ทธ์•„์›ƒ ๋ฒ„ํŠผ์„ ์‚ฌ์šฉํ•œ ํ›„์ธ ์ฃผ์†Œ๊ฐ€ "/profile"์ด๊ธฐ ๋•Œ๋ฌธ์—, Route๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๊ณ 
Redirect๊ฐ€ ๋™์ž‘ํ•˜์—ฌ ๋ฉ”์ธํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.

์ฐธ๊ณ ๋งํฌ
https://reactrouter.com/web/api/Redirect

๋Š๋‚€ ์ 

์‚ฌ์‹ค์€ ์ด๋ฒˆ ์—ฐ์ดˆ๋ถ€ํ„ฐ ๋ธ”๋กœ๊ทธ ํ™œ๋™์„ ํ•˜๋ฉด์„œ ๊ณต๋ถ€ ๊ธฐ๋ก์„ ์ž‘์„ฑํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ, ์‚ฌ๋žŒ์ด๋ผ๋Š”๊ฒŒ ๊ท€์ฐฎ์•„์ ธ์„œ..๋ฏธ๋ฃจ๊ฒŒ ๋˜์—ˆ๋‹ค..ใ…Žใ…Ž.. ๊ทธ๋ ‡๊ธฐ๋•Œ๋ฌธ์— ๋Šฆ์—ˆ์ง€๋งŒ ์ง€๊ธˆ๋ถ€ํ„ฐ๋ผ๋„ ๊พธ์ค€ํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋ ค๊ณ  ํ•œ๋‹ค!

0๊ฐœ์˜ ๋Œ“๊ธ€