[250423] TIL

Today I Learned (2025-04-23)

์ธ์ฆ ๋„๋ฉ”์ธ ๊ตฌํ˜„ TIL

์˜ค๋Š˜ ๋ฐฐ์šด ๊ฒƒ

์นด์นด์˜ค ์†Œ์…œ ๋กœ๊ทธ์ธ ๊ธฐ๋ฐ˜ ์ธ์ฆ ์‹œ์Šคํ…œ์„ ์„ค๊ณ„ํ•˜๊ณ  ๋Œํ•€ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํ•™์Šตํ–ˆ์Šต๋‹ˆ๋‹ค.

์ธ์ฆ ํ๋ฆ„

  1. ์˜จ๋ณด๋”ฉ โ†’ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญ
  2. ์นด์นด์˜ค ์ธ์ฆ โ†’ ์ฝœ๋ฐฑ์œผ๋กœ ์ธ์ฆ ์ฝ”๋“œ ํš๋“
  3. ์•ฝ๊ด€ ๋™์˜ โ†’ ์„œ๋น„์Šค/๊ฐœ์ธ์ •๋ณด/์œ„์น˜์ •๋ณด ๋™์˜
  4. ํ”„๋กœํ•„ ์„ค์ • โ†’ ๋‹‰๋„ค์ž„, ์†Œ๊ฐœ๊ธ€ ์ž…๋ ฅ
  5. ํ™ˆ ํ™”๋ฉด ์ง„์ž…

์ฃผ์š” ๊ตฌํ˜„ ์‚ฌํ•ญ

1. KakaoLoginButton

const handleLogin = async () => {
  const { redirect_url } = await AUTH_API.authorize();
  window.location.href = redirect_url;
};

2. ์ธ์ฆ ์ฝœ๋ฐฑ ์ฒ˜๋ฆฌ (SSR)

// /auth/callback
export const getServerSideProps = async ({ query }) => {
  const { code } = query;
  // ์ฝ”๋“œ๋กœ ํ† ํฐ ๋ฐœ๊ธ‰ ํ›„ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
  const { token } = await AUTH_API.getToken(code);
  return { redirect: { destination: '/auth/consent' } };
};

3. ์•ฝ๊ด€ ๋™์˜ ํŽ˜์ด์ง€ (CSR)

// ConsentForm ํ•ต์‹ฌ ๋กœ์ง
const handleSubmit = async () => {
  if (!allRequiredAgreed) return;
  await AUTH_API.consent({ privacy: true, location: true });
  router.push('/auth/signup');
};

4. ํšŒ์›๊ฐ€์ž… ์ •๋ณด ์ž…๋ ฅ (CSR)

// SignupForm ํ•ต์‹ฌ ๋กœ์ง
const onSubmit = async (data) => {
  const profileUrl = data.profileImage 
    ? await uploadImage(data.profileImage) 
    : null;
    
  await AUTH_API.completeSignup({
    nickname: data.nickname,
    introduction: data.bio,
    profile_image: profileUrl
  });
  
  router.push('/');
};

๊ธฐ์ˆ ์  ๊ณ ๋ ค์‚ฌํ•ญ

  • ๋ Œ๋”๋ง ์ „๋žต: ์ธ์ฆ ์ฝœ๋ฐฑ์€ SSR, ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜์ด ๋งŽ์€ ํŽ˜์ด์ง€๋Š” CSR ์‚ฌ์šฉ
  • ํ† ํฐ ๊ด€๋ฆฌ: HttpOnly ์ฟ ํ‚ค๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด๊ด€
  • ์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„: ์žฌ์‚ฌ์šฉ์„ฑ ๊ณ ๋ คํ•œ ๋ชจ๋“ˆํ™” (LoadingSpinner, ConsentForm ๋“ฑ)
  • ์œ ํšจ์„ฑ ๊ฒ€์ฆ: React Hook Form์œผ๋กœ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๊ฒ€์ฆ

Categories:

Updated:

Leave a comment