๋๋ถ๋ถ์ ์น์ฑ์๋ ์ธ์ฆ DOM์ด ํ์ํ๋ค.
์ธ์ฆ DOM =Authentication DOM
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํด์ผ๋ง ์ ๊ทผ ๊ฐ๋ฅํ ๊ตฌ์ญ์ด ์๋ค.
1. ๋ฆฌ์กํธ ์ฑ์์ ์ธ์ฆ์ด ์๋ํ๋ ์๋ฆฌ
2. ์ฌ์ฉ์ ์ธ์ฆ์ ์์ (๊ฐ์ , ๋ก๊ทธ์ธ, ๋ก๊ทธ์์, ๋ก๊ทธ์ธ ์ ๋ณดํธ๋ ๋ฆฌ์์ค์ ์ ๊ทผํ๋ ๋ฒ)
3. ์ฌ์ฉ์๊ฐ ํ์ด์ง ๋ ๋๋ ๋ก๊ทธ์ธ ์ ์งํด์ฃผ๋ ๊ธฐ๋ฅ & ์๋ ๋ก๊ทธ์์ ๊ธฐ๋ฅ
์น์ฌ์ดํธ์์ ์ธ์ฆ์ด ํ์ํ ์ด์
=> ๋ณดํธํด์ผ ํ ์ ๋ณด๊ฐ ์๋ค!!
์ ์ ๋น๋ฐ๋ฒํธ, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ ๋ฐ์ดํฐ ๋ฐ ๋ฏธ์ธ์ฆ ์ฌ์ฉ์์ ์ ๊ทผ์ด ์ ํ๋ ํ์ด์ง์ ๋ฆฌ์กํธ ์ฑ์ด ์์ฒญ์ ๋ณด๋ผ ๋ ๊ทธ ์์ฒญ์ ๋ฐ๋ API ์๋ ํฌ์ธํธ๊ฐ ๊ทธ๋ฐ ๋ฐ์ดํฐ์ ์ํ๋ค.
ํ๋กํ ํ์ด์ง ์์ฒด์๋ ์ ๊ทผ ์ ํ + ์์ฒญ๋ฐ๋ API ์๋ํฌ์ธํธ์๋ ์ ๊ทผ ์ ํ ๊ฑธ์ด์ผ ํ๋ค.
์ธ์ฆ์ด ์ด๋ป๊ฒ ์๋ํ ๊น?
์ผ๋ฐ์ ์ผ๋ก ์ธ์ฆ์ 2๋จ๊ณ๋ฅผ ๊ฑฐ์น๋ค.
1๋จ๊ณ = ์ฌ์ฉ์๊ฐ ์ ๊ทผ ํ๊ฐ ๋ฐ๊ธฐ
๋ก๊ทธ์ธ์ผ๋ก ์๊ฒฉ ์ฆ๋ช ํด์ ์ ๊ทผ ํ๊ฐ ๋ฐ์ ์ ์๋ค. ๋ก๊ทธ์ธ ์ ์๊ฒฉ ์ฆ๋ช ์ ๊ณตํ๋ฉด, ๋ฐ์ดํฐ๊ฐ ์๋ฒ๋ก ์ ์ก๋๋ค. ๊ทธ๋ฌ๋ฉด ์๋ฒ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ดํด์ ์ฌ์ฉ์์ ์์ด๋/๋น๋ฐ๋ฒํธ๋ฅผ ํ์ธํ๊ณ , ์ ํจ์ฑ์ด ๊ฒ์ฆ๋๋ฉด ์์ฒญ์ ๋ฐ์ ๋ฐฑ์๋ ์๋ฒ๊ฐ ์ ๊ทผ์ ํ๊ฐํ๋ค.
(๊ทธ๋ ๋ค๊ณ ํด์ yes/no ๋ก๋ง ์๋ตํ์ง๋ ์๋๋ค. )
2๋จ๊ณ = ์๋ฒ์ชฝ์์ ๋ณดํธ๋ ๋ฆฌ์์ค ๋ณด๋ด์ฃผ๊ธฐ
Server-side Session ์ด๋ Authentication Token์ ์ฌ์ฉํด์ผ ํ๋ค.
1. Server-side Session
์ฌ์ฉ์ ์ ๊ทผ์ ํ๊ฐํ ์๋ฒ๊ฐ ํ๊ฐ๋ฅผ ๋ฐ์ ํด๋ผ์ด์ธํธ(ํน์ ์ฌ์ฉ์)์ ๊ณ ์ ID๋ฅผ ์ ์ฅํ๋ค.
์๋ฒ๊ฐ ํน์ ํด๋ผ์ด์ธํธ์ ๊ณ ์ ID๋ฅผ ์์ฑํ๊ณ ์ ์ฅํ๊ธฐ ๋๋ฌธ์, ์ธ์ฆ์ ๊ฑฐ์น๋ ๋ชจ๋ ์ฌ์ดํธ ๋ฐฉ๋ฌธ์์ ๊ณ ์ ID๊ฐ ์๋ฒ์ ์ ์ฅ๋๋ค.
์ด ID๋ ์๋ฒ์๋ง ์ ์ฅ๋์ง ์๊ณ ํด๋ผ์ด์ธํธ์๊ฒ๋ ์ ์ก๋๋ค. ๊ทธ๋์ ์๋ฒ์ ํด๋ผ์ด์ธํธ ๋ชจ๋ ์ด ID๋ฅผ ์๊ณ ์๋ค.
๐ํ์์์ฒญ ์ฒ๋ฆฌ๋ฐฉ๋ฒ
ํด๋ผ์ด์ธํธ๊ฐ ID๋ฅผ ์๋ฒ์ ํ์ ์์ฒญ์ ๋ณด๋ผ ๋ ํจ๊ป ์ฒจ๋ถํ๋๋ฐ, ์๋ฒ๊ฐ ID๋ฅผ ์๊ณ ์์ผ๋ฏ๋ก ID๊ฐ ์ผ์นํ๋ฉด ์ ๊ทผ์ด ํ์ฉ๋๊ณ , ํ์ ์์ฒญ์ด ํ๊ฐ๋๋ค. ๊ทธ๊ฒ ์๋๋ฉด ๋ถ๊ฐ!
๐๋จ์ = ๋ฐฑ์๋์ ํ๋ก ํธ์๋์ ๊ฒฐํฉ์ด ๊ธด๋ฐํ๋ฉด ์๋ฌด ์ด์ ์์ง๋ง ๋ถ๋ฆฌ๋ผ ์๋ค๋ฉด ์ด์ผ๊ธฐ๊ฐ ๋ฌ๋ผ์ง๋ค.
(์๋ฒ๋ ํด๋ผ์ด์ธํธ์ ์ํ๋ฅผ ๋ณด์กดํ์ง ์๋ ๋ฌด์ํ์ด๊ธฐ ๋๋ฌธ์)
์ ์ํ ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด์ ์ ๋๋ค.
๐๋จ์ ํด๊ฒฐ๋ฐฉ๋ฒ
๋ฐฑ์๋์ ํ๋ก ํธ์๋ ๋ถ๋ฆฌ ์ํ๋ ํนํ ์ฑ๊ธ ํ์ด์ง ์ฑ ๊ฐ๋ฐ์์๋ Server-side Session ๋ง๊ณ Authentication Token ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ๋๋ค.
2. Authentication Token
์ฌ์ฉ์๊ฐ ์์ด๋๊ณผ ๋น๋ฐ๋ฒํธ๋ก ์๋ฒ์ ์๊ฒฉ ์ฆ๋ช ์ ๋ณด๋ด๋ฉด ์๋ฒ๊ฐ ๊ทธ๊ฑธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ ์์ด๋/๋น๋ฐ๋ฒํธ ์กฐํฉ๊ณผ ๋น๊ตํด ์ ํจ์ฑ์ ํ์ธํ๋ค. (์ฌ๊ธฐ๊น์ง Server-side Session ๋ฐฉ์๊ณผ ๊ฐ์)
๊ทธ๋ฐ๋ฐ ์๊ฒฉ์ด ์ฆ๋ช ๋๋ฉด ์๋ฒ๊ฐ ํ๊ฐ ํ ํฐ์ด๋ผ๋ ๊ฑธ ์์ฑํ๋ค.
(ํ ํฐ์ ์๋ฒ๊ฐ ํน์ ์๊ณ ๋ฆฌ์ฆ์ ๋ฐ๋ผ ์์ฑํ๋๋ฐ, ์ด๋ ์ค์ํ ๊ฑด ์๋ฒ๋ง ์๋ ํค๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ๋ฌธ์์ด๋ก ํด์ฑํ๋ค. )
ํ ํฐ์ ์๋ฒ์ ์ ์ฅ๋์ง ์๊ณ ํด๋ผ์ด์ธํธ์๊ฒ ๋ค์ ์ ์ก๋์ง๋ง ํ ํฐ์ ์์ฑํ๋ ๋ฒ์ ์๋ฒ๋ง ์๊ณ ์๋ค.!!
๐ํ์์์ฒญ ์ฒ๋ฆฌ๋ฐฉ๋ฒ
ํด๋ผ์ด์ธํธ๋ ์ด ํ ํฐ์ ์๋ฒ์ ๋ณดํธ๋ ๋ฆฌ์์ค์ ๋ณด๋ธ๋ค.
์๋ฒ๋ ์ธ์ ๊ธฐ๋ฐ ๊ธฐ๋ฒ๊ณผ ๋ฌ๋ฆฌ ID๋ฅผ ์ ์ฅํ์ง ์์์ง๋ง, ์์ ์ด ์์ฑํ ํ ํฐ์ธ์ง ํ์ธํ ์ ์๋ค.
์๋๋ฉด ํ ํฐ ์์ฑ์ ์ฌ์ฉ๋ ๊ฐ์ธํค๋ฅผ ์๋ ๊ฑด ์๋ฒ๋ฟ์ด๊ธฐ์!!
๊ทธ๋์ ๋ณดํธ๋ ๋ฆฌ์์ค์ ์ ๊ทผ ์์ฒญ์ ๋ณด๋ผ ๋ ์ฒจ๋ถ๋ ํ ํฐ์ ์ ํจ์ฑ์ ์๋ฒ๊ฐ ํ์ธํ ์ ์๋ ๊ฒ์ด๋ค.
ํ ํฐ์ด ์์กฐ๋๊ฑฐ๋ ๋ค๋ฅธ ํค๋ก ์์ฑ๋์ผ๋ฉด ์๋ฒ๊ฐ ์ด๋ฅผ ๊ฐ์งํ๊ณ ์ ๊ทผ์ ๊ฑฐ๋ถํ๋ค.
์ถ๊ฐ๊ณต๋ถ
Authentication Token์ ์ผ๋ฐ์ ์ผ๋ก 'JSON ์น ํ ํฐ (JWT)' ํ์์ผ๋ก ์์ฑ๋๋ค.
JWT๋ ๋ฐ์ดํฐ๋ฅผ ๋ฌธ์์ด๋ก ์ธ์ฝ๋ฉํ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ํด ๊ตฌ์ฑ๋ ๊ธด ๋ฌธ์์ด์ด๋ค. (private key์ ๋์์ผ๋ก ์๋ฒ์์๋ง ์ ์ ์๋ค. )
idToken์ด ๋ด๊ธด ์๋ต์ ๋ฐ์๋ค๋ฉด ์ฌ์ฉ์๊ฐ ์ ํจํ ์๊ฒฉ ์ฆ๋ช ์ ์ ๊ณตํ ๊ฒ์ด๋ค.
์ฌ๊ธฐ๊น์ง ๋ง์ณค๋ค๋ฉด, ์๋์ค์ธ ๋ฆฌ์กํธ ์ฑ ์ด๋๊ฐ์ ํ ํฐ์ ์ ์ฅํด์ผํ๋ค.
์?
๋ชจ๋ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํด์ผ ํ๋๊น!
ํ ํฐ์ app wide state ์ด์ด์ผ ํ๋ค. => ์ปจํ ์คํธ api or ๋ฆฌ๋์ค ํ์ฉํ๊ธฐ!
์ฐธ๊ณ )
const userIsLoggedIn = !!token;
์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ์ด๋ค.
๋ค๋ฅธ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ boolean ํ์ ์ผ๋ก ๋ช ์์ ์ผ๋ก ํ ๋ณํ(Type Conversion)ํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
์ฐธ ๋๋ ๊ฑฐ์ง ๊ฐ์ ๋ถ์ธ ๊ฐ์ผ๋ก ๋ฐ๊ฟ์ค๋ค.
ํ ํฐ์ด ๋น ๋ฌธ์์ด์ด ์๋๋ฉด true๋ฅผ ๋ฐํํ๊ณ
ํ ํฐ์ด ๋น ๋ฌธ์์ด์ด๋ฉด false๋ฅผ ๋ฐํํ๋ค.
์๋ ํํฐ API๋ก ์์ ํ๋ค๋ฉด ํ ํฐ์ ์ด๋ป๊ฒ ์ถ๊ฐํ๋์ง๋ ์๋ํฌ์ธํธ์ ๋ฐ๋ผ ๋ค๋ฅด๋ค.
์ฌ๊ธฐ์๋ body์ ์ถ๊ฐํ์ง๋ง, ๋ค๋ฅธ ์๋ํฌ์ธํธ๋ ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์๋ก ํ ํฐ์ ์ถ๊ฐํด์ผ ํ ์๋ ์๊ณ ,
์ด๋ค API ์๋ํฌ์ธํธ๋ headers์ ์ถ๊ฐํด์ผ ํ ์๋ ์๋ค.
๊ทธ๋์ ์๋ํํฐ API๋ก ์์ ์ค์ด๋ฉด API ๋ฌธ์๋ฅผ ๋ณด๊ณ ํ ํฐ ์ถ๊ฐ ๋ฐฉ์์ ํ์ธํ๊ธฐ!!
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate(); navigate('/home')
๋ก๊ทธ์์ ๊ธฐ๋ฅ์ ํ์ด์ด๋ฒ ์ด์ค์ ์์ฒญ์ ๋ณด๋ด์ง ์์๋ ๋๋ค.
์๋๋ฉด, ์ธ์ฆ ํ ํฐ ๋ฐฉ์์ ๋ก๊ทธ์ธํ ํด๋ผ์ด์ธํธ์ ์ด๋ ํ ์ ๋ณด๋ ์๋ฒ์ ์ ์ฅ๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค!
๊ทธ๋์ ๋ก๊ทธ์์ ์ ๋ฐ๊ฟ์ผํ ๊ฒ์ state ๋จ ํ๋์ด๋ค!
context-API์์ ํ ํฐ์ ๋น์ฐ๋ฉด ๋๋ค. (๋น ๋ฌธ์์ด์ด๋ null๋ก ์ค์ ํ๊ธฐ)
๋ก๊ทธ์ธ ์ํ๊ฐ ์๋ ๋๋ URL์ ์ง์ ‘/profile’์ ๋ถ์ฌ ์ ์ํ๋ฉด ํ๋กํ ํ์ด์ง๊ฐ ๋ฌ๋ค. (์ ๊ทผํ ์ ์๋๊ฒ ์ ์)
ํด๊ฒฐ๋ฐฉ๋ฒ => ๋ค๋น๊ฒ์ด์ ๊ฐ๋ ๊ธฐ๋ฅ ์ถ๊ฐํ๊ธฐ
** ๋ก๊ทธ์ธ ์ฌ๋ถ์ ๋ฐ๋ผ App.js์ ๋ผ์ฐํธ ์ค์ ์ ๋์ ์ผ๋ก ๋ฐ๊พธ๋ ๊ฒ์ด๋ค.
=> ์ฌ์ฉ์์ ํ์ฌ ์ธ์ฆ ์ํ๋ฅผ ํน์ ๋ผ์ฐํฐ์ ์กฐ๊ฑด์ผ๋ก ์ผ์ผ๋ฉด ๋๋ค.
import { useContext } from "react";
import AuthContext from "./store/auth-context";
function App() {
const authCtx = useContext(AuthContext);
return (
<Layout>
<Switch>
<Route path='/' exact>
<HomePage />
</Route>
{!authCtx.isLoggedIn && (
<Route path='/auth'>
<AuthPage />
</Route>
)}
{authCtx.isLoggedIn && (
<Route path='/profile'>
<UserProfile />
</Route>
)}
</Switch>
</Layout>
);
}
๐ ์ฌ์ฉ์๊ฐ ์ ํจํ์ง ์์ ๊ฒฝ๋ก๋ก ์ ์ํ๊ฑฐ๋ ๋ก๊ทธ์ธ ์์ด '/profile'์ ์ ์ํ ๋๋ง๋ค ์๋ํ๋ค. ๐
import { Switch, Route, Redirect } from "react-router-dom";
function App() {
return
<Route path='*'>
<Redirect to='/' />
</Route>
}
๋ค์ ๋ก๋ํ๊ฑฐ๋ URL์ ์ ๋ ฅํ ๋๋ง๋ค ์ธ์ฆ ์ํ๋ฅผ ์๋๋ค. ์๋๋ฉด ๋ฆฌ์กํธ ์ฑ์ ๋ค์ ์์ํ๋ ๊ฑฐ๋๊น!
๋ก๋ํ ๋๋ง๋ค ๋ฐ์ดํฐ๋ฅผ ์๊ณ ์ถ์ง ์๋ค๋ฉด ํ ํฐ์ ๋ฆฌ์กํธ ์ํ ๋ฐ๊นฅ ์ด๋๊ฐ์ ์ ์ฅํ๋ฉด ๋๋ค.
=> ๋ธ๋ผ์ฐ์ ์ ์๋ ์ ์ฅ ๋ฉ์ปค๋์ฆ์ ํ์ฉํ์. ex) ์ฟ ํค, ๋ก์ปฌ ์คํ ๋ฆฌ์ง => ๊ทธ๋ฌ๋ฉด ํ์ด์ง ๋ฆฌ๋ก๋ํด๋ ๋ฐ์ดํฐ ์ด์๋จ์ ์๋ค!
1. ๋ก๊ทธ์ธํ๋ฉด ํ ํฐ์ ์ ์ฅํ๊ณ ์ถ๋ค.
const loginHandler = (token) => {
setToken(token);
localStorage.setItem("token", token);
};
2. ๋ก๊ทธ์์ํ๋ฉด ํ ํฐ์ ์ง์ฐ๊ณ ์ถ๋ค.
const logoutHandler = () => {
setToken(null);
localStorage.removeItem("token");
};
3. ํ์ด์ง๊ฐ ๋ก๋๋๋ฉด ๋ก์ปฌ ์คํ ๋ฆฌ์ง๋ฅผ ๋ณด๊ณ ํ ํฐ์ด ์์ผ๋ฉด, ํ ํฐ์ ์ด์ฉํด์ ์ฌ์ฉ์๊ฐ ์ฒ์์ ์ ์์ฒญ์ ๋ณด๋ด์ง ์๊ฒ ํ๊ณ ์ถ๋ค.
const initialToken = localStorage.getItem("token"); // ์ ํํ๊ฒ ํ๊ธฐ ์ํด์ ์ํ๋ฅผ ์ด๊ธฐํ
const [token, setToken] = useState(initialToken);
ํ ํฐ์ด ๋ง๋ฃ๋๋ฉด ์๋์ผ๋ก ์ฌ์ฉ์ ๋ก๊ทธ์์ ํ๊ธฐ
๋ฐฉ๋ฒ1. ํ์ด๋จธ ์ค์
๋ฐฉ๋ฒ2. ๋ก์ปฌ ์ ์ฅ์์ ๋จ์ ์๊ฐ ์ ์ฅํ๊ธฐ
๋ง๋ฃ์๊ฐ, ํ์ด๋จธ ์ค์ ํ๊ธฐ (ํ์๊ฐ์ด ๋ํดํธ)
//Auth-context.js
const logoutHandler = () => {
setToken(null);
localStorage.removeItem("token");
};
const loginHandler = (token, expirationTime) => {
setToken(token);
localStorage.setItem("token", token);
const remainingTime = calculateRemainingTime(expirationTime);
setTimeout(logoutHandler, remainingTime);
};
//Authform.js
.then((data) => {
console.log(data);
const expirationTime = new Date(
new Date().getTime() + +data.expiresIn * 1000
);
authCtx.login(data.idToken, expirationTime.toISOString());
history.replace("/"); // ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ ๋ฐ ๋ก๊ทธ์ธ ํ์ ๋ฆฌ๋๋ ์
ํ๊ธฐ
})
๐ ์๋ชป๋ ๊ฐ๋ ์ ๋ฌ์ด ์๋ค๋ฉด ๋๊ธ ๋ถํ๋๋ฆฝ๋๋ค. ์ ์ ์ฑ์ฅ์ ํฐ ๋์์ด ๋ฉ๋๋ค๐ค
'๐ฅFrontEnd > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
axios.get์ fetch ์ฐจ์ด (0) | 2022.09.05 |
---|---|
TIL) ๋ฆฌ์กํธ์์ <a> ํ๊ทธ? Link ์ปดํฌ๋ํธ? (0) | 2022.09.02 |
React 18 ๋ฒ์ ์ดํ) React์์ ์ฝ๋ ๋ถํ ํ๋ ๋ฐฉ๋ฒ, dynamic import ๋ฐฉ๋ฒ, React.lazy์ Suspense (0) | 2022.07.28 |
useRef๋, useRef ์ฌ์ฉ๋ฐฉ๋ฒ, useRef ์ฌ์ฉ ์์ (0) | 2022.07.27 |
Custom Hook, Custom Hook ์ฅ์ , ๊ท์น (0) | 2022.07.27 |