Firebase 시리즈 #2: AI 한자 추천 & 필기 학습 플랫폼
₩29,700
초급 / gemini, HTML/CSS, TailwindCSS, JavaScript, Firebase
🔥 한자 학습을 위한 맞춤형 플랫폼 구축! Google Gemini AI와 Firestore를 활용해 나만의 한자 단어장, 획순 애니메이션, 필기 인식까지 직접 구현해보세요!
초급
gemini, HTML/CSS, TailwindCSS
안녕하세요! 서강대학교 컴공과를 졸업하고 현재 대학원 진학을 준비 중인 학생입니다.
고등학교 때 우연히 풀스택 웹 개발과 파이썬을 활용한 자동 매매를 시작하면서 프로그래밍에 빠지게 되었습니다.
그 후 다양한 프로젝트와 프로그래밍 과외활동을 경험하며 실력과 노하우를 공유했습니다. 이러한 경험을 통해 프로그래밍을 처음 접하는 분들에게도 "이렇게 쉬울 수 있구나!"라는 느낌을 줄 수 있는 강의를 만들고자 노력하고 있습니다.
실용적인 예제와 친근한 설명으로 여러분의 학습을 돕고 싶습니다. 감사합니다.
Firebase 시리즈 #2: AI 한자 추천 & 필기 학습 플랫폼
₩29,700
초급 / gemini, HTML/CSS, TailwindCSS, JavaScript, Firebase
🔥 한자 학습을 위한 맞춤형 플랫폼 구축! Google Gemini AI와 Firestore를 활용해 나만의 한자 단어장, 획순 애니메이션, 필기 인식까지 직접 구현해보세요!
초급
gemini, HTML/CSS, TailwindCSS
Firebase 시리즈 #1: 소셜 로그인·휴대폰·위치 인증 완벽 가이드
₩18,700
초급 / HTML/CSS, TailwindCSS, JavaScript, Firebase, 서버리스
5.0
(2)
🔥 HTML + Tailwind CSS + 순수 JavaScript만으로 완성하는 Firebase 사용자 인증! 소셜 로그인·휴대폰·위치 인증까지, 복잡한 백엔드 없이 쉽고 빠르게 계정 시스템 구축합니다.
초급
HTML/CSS, TailwindCSS, JavaScript
React, Node.js, MongoDB로 만드는 나만의 회사 웹사이트: 완벽 가이드
₩44,000
중급이상 / React, Node.js, MongoDB, HTML/CSS, JavaScript
5.0
(3)
React, Node.js, MongoDB를 활용해 회사 웹사이트를 직접 제작하는 과정을 배울 수 있는 실전 강의입니다. 간단한 React, Node.js 배경으로 풀스택 프로젝트를 같이 만들어요!
중급이상
React, Node.js, MongoDB
질문&답변
초기 설정에 대한 질문
안녕하세요. 질문 남겨주셔서 감사합니다! Q1. Frontend와 Backend 폴더에 node-modules를 각각 만든 이유A1. 일단 Frontend 폴더와 Backend 폴더를 나눠서 개발을 진행한 이유를 설명드리면두 영역은 역할과 기술 스택이 완전히 다르기 때문에, 프로젝트 구조상 기능별로 분리하는 것이 효율적이기 때문입니다.프론트엔드는 React-Vite 라이브러리를 사용해서 사용자 인터페이스(UI)를 구성하고, 브라우저 환경에서 동작하는 코드가 많습니다. 반면, 백엔드는 Express 프레임워크로 서버 API를 구성하며, 데이터베이스와의 통신이나 인증 로직 등 서버 측 비즈니스 로직을 담당합니다.물론, React-Vite와 Express를 같은 루트 폴더에 함께 설치해서 운용하는 것도 가능합니다. 실제로 하나의 package.json에 프론트엔드와 백엔드에서 사용하는 모든 의존성을 함께 설치하고, React 개발 서버와 Express 서버를 동시에 구동하도록 npm scripts를 설정하는 방식이 있습니다.이런 방식은 초기 개발 속도가 빠르고 폴더 구조가 단순하다는 장점이 있어서, 특히 혼자 개발하거나 소규모 프로젝트에서는 사용해볼 만합니다.다만 이 구조는 다음과 같은 단점이 있습니다:의존성 충돌 가능성: 프론트엔드와 백엔드에서 사용하는 동일한 패키지(예: dotenv, axios)의 버전 충돌이 발생할 수 있습니다.빌드 및 배포의 혼합: React 빌드 파일(dist/)과 백엔드 서버 파일이 같은 공간에 얽히면, 정리나 배포 시 혼동이 생길 수 있습니다.테스트 및 CI/CD의 복잡성 증가: 두 환경을 분리해서 테스트하거나, 각각 배포하고자 할 때 설정이 복잡해집니다.말씀하신 node_modules도 동일한 이유입니다.프론트엔드와 백엔드가 같은 루트 폴더에서 작동한다면 하나의 node_modules만으로도 모든 패키지를 공유할 수 있지만, 이는 곧 두 영역의 의존성 관리가 얽히게 된다는 단점을 의미합니다. 예를 들어, 프론트에서만 필요한 vite, react-dom 같은 패키지와 백엔드에서만 쓰는 express, cors 등이 한 공간에 뒤섞이면, 어떤 패키지가 어느 역할을 위해 설치된 것인지 파악하기 어렵고, 불필요한 패키지까지 함께 설치/배포되는 비효율이 발생합니다.결국 이런 이유들로 인해, 프로젝트를 보다 명확하게 관리하고 확장성을 고려하려면 초기부터 프론트엔드와 백엔드를 폴더 단위로 분리하고, node_modules 역시 각자 독립적으로 유지하는 구조가 더 바람직합니다.Q2. 깃허브에 node-modules가 업로드 되지 않은 이유. 다른 환경에서 개발을 이어나가고 싶을 때 방법A2. node_modules 폴더는 용량이 크고 수많은 파일을 포함하고 있어, GitHub 같은 버전 관리 시스템에 업로드하게 되면 저장소가 불필요하게 무거워지고 관리가 어려워집니다. 실제로 프로젝트 내의 node_modules 폴더의 용량을 확인해보시면 수십~수백 MB의 용량일 것입니다.또한, 이 폴더는 각 개발 환경에 따라 자동으로 다시 생성할 수 있기 때문에, 직접 업로드할 필요도 없습니다. 그래서 일반적으로 .gitignore 파일에 node_modules를 명시해 Git 추적 대상에서 제외하게 됩니다.다른 개발 환경에서 프로젝트를 이어받아 작업하려면, 루트 폴더에 포함된 package.json과 package-lock.json만 있으면 됩니다. 이 파일들은 프로젝트에 필요한 모든 의존성과 버전 정보를 담고 있어서, 동일한 개발 환경을 자동으로 복원할 수 있도록 도와줍니다.특히 package.json은 단순히 패키지 목록을 담는 것을 넘어서, 프로젝트 이름, 설명, 실행 스크립트, Node.js 버전 등 핵심 설정 정보를 포함하고 있어 협업과 유지보수, 배포의 기반이 되는 중요한 파일입니다.따라서 node_modules 없이도, 이 설정 파일들만 잘 유지하면 npm install 명령어를 통해 언제든지 같은 개발 환경을 재현하며 작업을 이어갈 수 있습니다.Q3. Create React App(CRA)로 만드는 법과 Vite, Next.js로 만드는 방법 중 Vite를 고른 이유가 있을까요?Create React App(CRA), Vite, Next.js 중에서 Vite를 선택한 이유는 개발 속도가 빠르고 설정이 간편하기 때문입니다. Vite는 코드 변경 시 실시간으로 빠르게 반영되기 때문에, 개발하면서 더 효율적으로 작업할 수 있습니다. 또한, Vite는 빌드 속도가 빠르고, 설정이 간단해서 프로젝트를 빠르게 시작할 수 있습니다. Next.js는 추가적인 서버 사이드 렌더링(SSR) 같은 기능을 제공하지만, 단순한 React 애플리케이션을 만들기엔 Vite가 더 적합하다고 생각했습니다.도움이 되셨길 바랍니다. 감사합니다!
질문&답변
소스코드 다운로드 링크의 접속이 안됩니다
안녕하세요, 문의 감사합니다.먼저, 불편을 드려 정말 죄송합니다. 클라우드 파일을 정리하던 중 실수로 링크된 소스코드 파일이 삭제된 것 같습니다. 현재는 복구를 완료하였으니, 노션에 있는 기존의 링크를 통해 다시 다운로드해보시면 정상적으로 접속하실 수 있습니다.구글 드라이브:https://drive.google.com/file/d/1RGAl101rHTp2NjdWQ1Mqi_EsruKPEEYN/view?usp=sharing네이버:https://naver.me/FRLFhBNm또한, 각 챕터별 수업 노트 하단에도 깃허브(GitHub) 링크를 함께 안내해드리고 있으니, 필요하실 경우 해당 경로를 통해서도 소스코드를 받으실 수 있습니다.혹시 여전히 문제가 발생한다면 언제든지 말씀해 주세요. 다시 한 번 불편을 드린 점 사과드립니다.감사합니다.
질문&답변
배포 강의에서 Blocked request 경우, vite.config.js 파일도 수정해야되나요?
안녕하세요. 질문 주셔서 감사합니다!Blocked request. This host ("5d39-218-159-221-155.ngrok-free.app") is not allowed. To allow this host, add "5d39-218-159-221-155.ngrok-free.app" to server.allowedHosts in vite.config.js.이 에러는 Vite 개발 서버가 외부 도메인(ngrok 주소 등)에서의 접근을 기본적으로 차단하기 때문에 발생한 문제입니다. 해결 방법은 질문자님이 말씀하신대로 vite.config.js 파일 수정입니다!강의에서는 Vite 버전이 낮거나 allowedHosts 기본 제한이 없던 환경이었기 때문에, ngrok 주소로 접속해도 별도 설정 없이 작동했던 것으로 보입니다. vite.config.js 수정 코드// vite.config.js import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], server: { allowedHosts: ['5d39-218-159-221-155.ngrok-free.app'], // ngrok 주소를 입력해주세요! }, });또한, 개발용으로 ngrok를 자주 쓸 경우엔 allowedHosts: 'all'로 설정해두면 편합니다.server: { allowedHosts: 'all', }도움이 되었길 바랍니다. 감사합니다!
질문&답변
rafce 기본 템플릿 적용 및 폴더 파일 대소문자 관련 부분
안녕하세요. 남겨주신 질문에 답변 드리겠습니다.Q1. 기본 템플릿 생성 rafce가 이전 파일이름을 작성하는 경우A1. 상황을 다시 요약해보면NavBar.jsx → 처음에 만들고 rafce (React Arrow Function Component Export) 사용NavBar.jsx 파일을 삭제함새로 Navbar.jsx 파일 만들고 rafce 입력했는데여전히 NavBar (이전 이름)으로 컴포넌트가 만들어짐이 현상은 보통 VSCode의 확장 프로그램(예: ES7+ React/Redux Snippets)이 자동으로 파일명을 기반으로 컴포넌트 이름을 생성하기 때문에 발생합니다.VSCode가 내부적으로 이전 파일명이나 경로 정보를 캐시하거나 기억하고 있어서, 새로 만든 파일이 실제로는 Navbar.jsx더라도, 예전에 만들었던 NavBar.jsx 파일로 인식하여 컴포넌트 이름을 NavBar로 자동 완성하는 경우가 있습니다.이 경우에는 자동 생성된 컴포넌트 이름을 직접 Navbar로 수정해 주시는 것이 가장 확실하며, 필요시 VSCode를 재시작하면 캐시된 이름 정보가 초기화되어 해결할 수 있습니다. Q2. Components 및 Page 폴더 파일 대소문자 구분 생성 이유A2. Components 및 Pages 폴더에서 대소문자를 구분하여 파일이나 폴더 이름을 작성하는 이유는 그냥 제 스타일입니다. 사실 폴더나 파일 이름에 대한 대소문자 사용에는 명확한 공식 규칙은 없지만, 일반적으로 다음과 같은 컨벤션(관례)이 존재하긴 합니다:React 컴포넌트 파일: PascalCase (ex. NavBar.jsx, UserCard.jsx)일반 변수, 함수: camelCase (ex. handleClick, userName)폴더 이름: kebab-case 또는 PascalCase (개발자마다 다름)하지만 개인 프로젝트나 팀 내에서 특별한 컨벤션이 없다면 질문자님께서 구분하기 편한 대로 작성하셔도 전혀 문제 없습니다. 감사합니다!
질문&답변
실무에서 tailwind css 사용시 구조 질문드립니다.
안녕하세요. Tailwind CSS 실무 사용 여부에 대해 답변하겠습니다.실무에서는 Tailwind CSS, Instagram이나 Airbnb처럼 내부 스타일 시스템(CSS Modules, CSS-in-JS), 또는 Google/Youtube처럼 자체 빌드된 CSS 프레임워크 등 여러 가지 기법으로 디자인을 구현합니다.1) Tailwind CSS를 사용중인 웹 서비스 예시실제 예시로 Tailwind CSS를 사용 중인 대표적인 서비스 중 하나가 Supabase입니다.Supabase 웹페이지의 코드(supabase/apps/ui-library/components at master · supabase/supabase)를 확인해보면 다음과 같이 HTML 요소에 Tailwind 유틸리티 클래스가 직접 적용된 모습을 볼 수 있습니다:(supabase mode-toggle.tsx 예제코드)'use client' import { useTheme } from 'next-themes' import * as React from 'react' import { Moon, Sun } from 'lucide-react' import { Button_Shadcn_ } from 'ui' export function ModeToggle() { const { setTheme, resolvedTheme } = useTheme() const [, startTransition] = React.useTransition() return ( { startTransition(() => { setTheme(resolvedTheme === 'dark' ? 'light' : 'dark') }) }} size="icon" variant="ghost" > Toggle theme ) }또한 Supabase는 block-item.tsx, command-menu.tsx, theme-switcher-dropdown.tsx, top-navigation.tsx 등에서 볼 수 있듯이, 전체 웹페이지를 컴포넌트 하나하나를 잘게 쪼개어 관리하는 구조를 사용하고 있습니다. Supabase처럼 컴포넌트를 잘게 나누고 관리하는 구조를 사용하면, 이러한 단점을 최소화하면서도 Tailwind의 생산성을 유지할 수 있습니다.즉, 질문자님이 말씀하신 Tailwind CSS의 단점을 실무에서는 컴포넌트화와 구조화로 보완하고 있는 셈입니다. 2) 내부 스타일 시스템(CSS Modules, CSS-in-JS) 사용중인 웹 서비스 예시(인스타그램 로그인 폼 클래스 예시)(사진)위 사진처럼 인스타그램은 Tailwind CSS와는 다르게, x972fbf, xdt5ytf, x78zum5 같은 난독화된 클래스명을 사용하여 자체적인 내부 CSS 스타일 시스템을 구축해 사용하고 있습니다.자체적인 내부 CSS 스타일 시스템의 이유 2가지코드 최적화 및 번들 사이즈 최소화클래스명을 짧고 해시처럼 만들면 전체 HTML과 CSS의 용량을 줄일 수 있어 페이지 로딩 속도가 향상됩니다.이런 방식은 빌드 도구(예: Webpack, Metro, Parcel)로 CSS를 압축할 때 자주 사용됩니다.크롤링 방지 및 보안 목적사람이 이해할 수 없는 클래스명은 웹 스크레이퍼나 자동화된 봇이 DOM 구조를 분석하기 어렵게 만듭니다.특히 로그인 페이지처럼 민감한 인터페이스에서는 자동화 로그인 시도나 악성 크롤링을 방지하는 효과도 있습니다.결과적으로 인스타그램은 React 및 PHP 기반의 재사용 가능한 컴포넌트 시스템을 사용하며, 많은 개발자들이 협업하고 다양한 상황(크롤링, 웹사이트 로딩속도, AddBlock 방지)에 대응하기 위해 구조가 깊고 복잡해졌으며 Atomic CSS 시스템(Stylex)을 사용하여, 각 클래스가 하나의 속성만을 가지도록 설계해 스타일시트 크기를 최소화하고 있습니다. Q. 만약 html 디자이너가 따로 있을때는 tailwindcss를 사용하지 않나요?A. 말 그대로 디자이너는 Figma, Zeplin, Adobe XD 등으로 UI 시안을 제작할 뿐이고,해당 시안에 맞춰 실제 개발이 이뤄질 수만 있다면,Tailwind CSS를 쓰든 CSS Modules를 쓰든 회사마다 기술 스택, 협업 문화, 이후의 유지보수/인수인계 방식에 따라 달라질 것으로 예상됩니다.즉, 실무에서는 팀 규모, 프로젝트 특성, 유지보수 전략 등에 따라 Tailwind CSS, 내부 스타일 시스템, 자체 빌드 프레임워크 등 다양한 방식이 선택되고 있습니다. 중요한 것은 어떤 기술을 사용하느냐보다, 그 기술을 팀과 프로젝트에 맞게 어떻게 구조화하고 관리하느냐입니다.Tailwind CSS의 클래스가 많아 보일 수 있지만, Supabase처럼 잘게 나눠진 컴포넌트 구조로 관리하면 충분히 실무에서도 효율적으로 활용할 수 있습니다.
질문&답변
Ch1-4. 네비게이션바 컴포넌트 만들기(1부) 에서 오류질문
안녕하세요. Ch.1-4 네비게이션 바 코드 스타일 작성에 대해 답변하겠습니다.React 컴포넌트를 작성할 때는 화살표 함수(Arrow Function)를 자주 사용합니다. 이때 JSX를 반환하는 방식에는 두 가지가 있습니다: 암시적 반환 (implicit return) 과 명시적 반환 (explicit return) 입니다. 아래 예제를 통해 두 방식의 차이를 살펴보겠습니다.1. 암시적 반환 (Implicit Return) 노션코드const MenuItem = ({ path, label, onClick }) => ( {label} );함수 몸체에 중괄호 {}를 사용하지 않고, 소괄호 () 안에 JSX를 바로 작성합니다.return 키워드를 생략해도 자동으로 JSX를 반환합니다. 2. 명시적 반환 (Explicit Return) 질문자님 코드const MenuItem = ({ path, label, onClick }) => { return ( {label} ); };함수 몸체에 중괄호 {}를 사용하고, JSX를 return 키워드로 명시적으로 반환합니다.조건문, 변수 선언, 로직 추가 등이 필요한 경우에는 이 방식이 유리합니다.두 코드 모두 단순히 작성 방식의 차이일 뿐이며, 실행에는 전혀 문제가 없습니다.첫 번째 코드는 암시적 반환(implicit return)을 사용해 보다 간결하게 작성되었고,두 번째 코드는 명시적 반환(explicit return)으로 JSX를 return문을 통해 명확히 반환하는 방식입니다.어떤 방식을 사용해도 동일하게 작동하며, 상황에 따라 선택하시면 됩니다.다만, 질문자님께서 올려주신 코드에서 컴포넌트 이름이 MenuItem이 아닌 Menuitem으로 작성된 부분이 보입니다.오타 부분 확인해보시고, 그래도 해결되지 않으면 다시 답변 남겨주세요. 감사합니다!
질문&답변
로그아웃 시 토큰 검증 오류 응답
안녕하세요. 남겨주신 토큰 검증 오류 시 로그아웃 처리 방식에 대한 질문에 답변 드리겠습니다.1. 로그아웃 로직 설명로그아웃 과정은 다음과 같습니다. 프론트엔드에서 백엔드로 로그아웃 요청을 보내면, 먼저 해당 관리자가 실제 관리자 계정인지 토큰을 검증한 후, user.isLoggedIn 값을 false로 업데이트합니다.그 후, res.clearCookie()를 사용하여 클라이언트의 쿠키에서 토큰을 삭제하는 방식으로 로그아웃이 처리됩니다.2. 처음 코드 작성 의도제가 처음 코드를 작성할 때는, 토큰 검증이 실패했다는 것은 해당 사용자가 유효한 관리자가 아니라는 의미이므로, isLoggedIn 상태를 변경할 필요가 없다고 판단했습니다.하지만 보안상 로그아웃 처리는 반드시 필요하므로, 토큰 검증 여부와 관계없이 res.clearCookie()를 통해 클라이언트의 쿠키 토큰을 삭제하고 로그아웃이 되도록 했습니다.3. 질문해주신 내용에 대한 피드백다만, 질문자님께서 지적해주신 대로, 토큰 검증이 실패했을 때 isLoggedIn 값을 변경하지 않으면, DB 상에서는 여전히 로그인 상태(isLoggedIn = true)로 남아있을 수 있습니다.이 상태에서 다시 로그인을 시도하면, 이미 로그아웃되었지만 DB에서는 여전히 로그인 중으로 판단되므로, 로그인도 하지 못하는 상태가 될 수 있습니다.이 부분을 고려하면, 토큰 검증이 실패하더라도 isLoggedIn = false로 변경하는 것이 더 적절한 방식입니다.4. 코드 수정 및 사과 말씀제가 처음 코드 작성 시 이 부분을 충분히 고려하지 못했던 것 같습니다. 말씀해주신 덕분에 더 나은 방식으로 개선할 수 있었고, 이에 대해 감사드립니다. 아래는 토큰 검증이 실패했더라도 강제 로그아웃되는 코드입니다. 참고해 주세요.router.post("/logout", async (req, res) => { try { const token = req.cookies.token; if (!token) { return res.status(400).json({ message: "이미 로그아웃된 상태입니다." }); } let user = null; try { const decoded = jwt.verify(token, process.env.JWT_SECRET); user = await User.findById(decoded.userId); } catch (error) { console.log("토큰 검증 오류: ", error.message); } if (user) { user.isLoggedIn = false; await user.save(); } res.clearCookie("token", { httpOnly: true, secure: false, sameSite: "strict", }); if (!user) { return res.status(401).json({ message: "유효하지 않은 토큰입니다. 강제 로그아웃되었습니다." }); } res.json({ message: "로그아웃되었습니다." }); } catch (error) { console.log("로그아웃 오류: ", error.message); res.status(500).json({ message: "서버 오류가 발생했습니다." }); } });
질문&답변
import Hero from './Hero' 오류 문의
안녕하세요. Already included file name ~~ Root file specified for compliation 오류에 대해 답변드립니다. "Already included file name ~~ Root file specified for compilation" 오류는 파일 이름의 대소문자 불일치나 파일 경로 문제로 인해 발생하는 에러입니다. 이 오류는 특히 Windows와 같이 파일 시스템이 대소문자를 구분하지 않는 환경에서 작업할 때 자주 나타납니다.파일 이름 대소문자 불일치:예를 들어, 처음 파일 생성 시 hero.jsx로 작성한 뒤 나중에 파일 이름을 Hero.jsx로 변경했지만, IDE나 빌드 도구(예: Webpack, Babel 등)가 이전 파일 이름을 캐싱하고 있어 import 경로가 여전히 import Hero from './hero';로 처리되는 경우 문제가 발생할 수 있습니다. 이로 인해 동일한 파일을 중복으로 인식하거나, 변경된 파일 이름을 제대로 반영하지 못해 충돌이 발생할 수 있습니다.IDE 또는 캐시 문제:Visual Studio Code와 같은 IDE가 파일 이름 변경 사항을 즉시 반영하지 못하고 이전 상태를 참조하여 문제가 발생할 수 있습니다.해결방법JavaScript 서버 재시작:Visual Studio Code에서 JavaScript 서버를 재시작합니다.Visual Studio Code에서 명령 팔레트 열기: Ctrl + Shift + P "JavaScript: Restart JS Server" 선택.IDE 완전 종료 및 재실행:Visual Studio Code를 완전히 종료한 뒤 다시 실행하여 캐시를 초기화합니다.위에 방법으로 해결이 안되시는 경우node_modules package-lock.json 삭제 후 재설치:프로젝트 폴더 내의 node_modules 디렉토리와 package-lock.json 파일을 삭제 후 npm install을 통해 패키지들을 다시 설치합니다.그래도 안되실 경우 마지막으로 Ch2-1의 프로젝트를 다시 다운로드하여 동일하게 진행해 주세요. 질문해주셔서 감사드립니다. 언제든지 추가 질문이 있으시면 편하게 문의해 주세요.
질문&답변
tailwind css 설치 관련 문의
안녕하세요. Tailwind CSS 설치 문제에 대해 답변드립니다.설치 문서에서 4번 단계(npx tailwindcss -i ./src/input.css -o ./src/output.css --watch) 해당 명령어는 Tailwind CSS를 수동으로 빌드하여 사용할 때 필요한 명령어입니다. 간단히 설명하면, Tailwind CSS의 원본 스타일(input.css)을 output.css로 변환하고, 실시간 변경 사항을 감지(watch)하는 역할을 합니다. 그러나, Vite 환경에서는 불필요한 단계이므로 혼동이 있으셨을 것 같습니다.-i ./src/input.css → 입력 파일 (Tailwind의 원본 CSS)-o ./src/output.css → 출력 파일 (변환된 CSS)--watch → 실시간으로 파일을 감지하여 변경 사항을 즉시 반영죄송하지만, 아래의 링크의 설치 공식문서를 참고하셔서 React + Vite 프로젝트를 재생성한 후, 1-2 강의를 그대로 진행하시면 무리 없이 Tailwind CSS 설치가 가능합니다.👉 Tailwind CSS + Vite 3.4.17 설치 공식문서귀한 시간을 내어 확인해 주셔서 진심으로 감사드립니다. 🙇♂
질문&답변
logout 기능에서 req.cookies.token == undefined가 되는 문제
안녕하세요. 남겨주신 질문에 답변 드리겠습니다.Q1. logout 기능에서 req.cookies.token == undefined가 되는 문제.1) GET 요청에서는 쿠키가 전달되고, POST 요청에서는 전달되지 않았던 이유router.get()에서는 쿠키(req.cookies.token)가 정상적으로 전달되었지만, router.post()에서는 undefined가 발생한 이유는 쿠키의 설정 값 때문입니다.secure: "production" 설정 문제secure 옵션은 true 또는 false로 설정해야 하는데, "production"(문자열)로 설정하면 브라우저가 이를 인식하지 못하고 쿠키를 설정하지 않습니다.결과적으로 POST 요청에서 쿠키가 제대로 전달되지 않았습니다.sameSite: "strict" 설정 문제sameSite: "strict"는 같은 도메인 내 요청에서만 쿠키를 포함하도록 제한합니다.GET 요청은 단순 요청이라 쿠키가 포함될 수 있었지만, POST 요청은 보안 정책에 의해 쿠키가 전송되지 않았습니다.해결 방법백엔드 user.js 96줄 기준으로 다음과 같이 수정하면 GET과 POST 요청에서 모두 쿠키를 정상적으로 받을 수 있습니다.res.cookie("token", token, { httpOnly: true, secure: false, sameSite: "None", // CORS 환경에서 POST 요청 허용 maxAge: 24 * 60 * 60 * 1000, });추가적으로, 위 해결 방법을 적용하셨음에도 불구하고 req.cookies.token이 undefined로 출력되는 경우, 번거로우시겠지만 ch5-2 GitHub 저장소에서 소스코드를 다운로드받아 해당 코드에서 테스트해 주시기를 부탁드립니다.📌 🔗 5-2 GitHub 저장소정확한 원인을 파악하는 데 있어 조금 더 구체적인 환경에서 테스트가 필요하여 요청드리는 점, 불편을 끼쳐드려 죄송합니다. 그리고 귀한 시간을 내어 확인해 주셔서 진심으로 감사드립니다.