안녕하세요! 서강대학교 컴공과를 졸업하고 현재 대학원 진학을 준비 중인 학생입니다.
고등학교 때 우연히 풀스택 웹 개발과 파이썬을 활용한 자동 매매를 시작하면서 프로그래밍에 빠지게 되었습니다.
그 후 다양한 프로젝트와 프로그래밍 과외활동을 경험하며 실력과 노하우를 공유했습니다. 이러한 경험을 통해 프로그래밍을 처음 접하는 분들에게도 "이렇게 쉬울 수 있구나!"라는 느낌을 줄 수 있는 강의를 만들고자 노력하고 있습니다.
실용적인 예제와 친근한 설명으로 여러분의 학습을 돕고 싶습니다. 감사합니다.
Courses
Reviews
- Voting Community Platform with React & FastAPI: Monetization through Payment Systems!
- Voting Community Platform with React & FastAPI: Monetization through Payment Systems!
- Building Your Own Company Website with React, Node.js, MongoDB: Complete Guide
- Building Your Own Company Website with React, Node.js, MongoDB: Complete Guide
- Building Your Own Company Website with React, Node.js, MongoDB: Complete Guide
Posts
Q&A
일렉트론 패키징 및 배포 관련 질문
안녕하세요! 좋은 질문 감사합니다말씀하신 대로 React 프로젝트를 정적 파일로 빌드 후 loadFile를 통해 온라인이 아닌 오프라인에서도 ElectronJS GUI 앱을 사용할 수 있습니다. 다만, Electron에서 loadURL()과 loadFile() 모두 React 앱을 불러오는 데 사용할 수 있지만, 두 방식은 용도와 특징이 조금 다릅니다.loadURL() 방식loadURL()은 개발 서버나 배포된 웹 주소를 불러오는 방식입니다.예를 들어, 개발 중에는 http://localhost:3000으로,배포 후에는 Firebase, Vercel, Netlify 등에 배포된 React 사이트 주소를 불러올 수 있습니다.이 방식의 가장 큰 장점은 Electron 앱을 다시 패키징하지 않아도 된다는 점입니다.React 쪽 코드만 수정하고 다시 배포하면, Electron 앱은 그대로 두고도 최신 버전의 웹 UI를 자동으로 반영할 수 있습니다.loadFile() 방식반면 loadFile()은 npm run build로 만들어진 정적 파일(index.html)을 직접 로드하는 방식입니다.이 방법은 완전히 오프라인 환경에서도 동작 가능하다는 장점이 있습니다.하지만 React 코드를 수정할 때마다 다시 빌드하고,그 결과물을 Electron 안에 다시 넣어 앱을 재패키징해야 하는 번거로움이 있습니다. 강의에서 제가 loadURL() 방식으로 Firebase에 배포된 React 앱을 불러온 이유는,Electron이 한 번 배포된 이후에도 React 웹사이트만 따로 수정하고 재배포할 수 있게 하기 위해서입니다.loadFile()을 사용하면 정적 파일이 Electron 내부에 포함되기 때문에, UI를 조금만 수정해도 앱 전체를 다시 빌드하고 패키징해야 합니다.하지만 loadURL()로 Firebase에 배포된 주소를 불러오면, Electron 앱은 그대로 두고 React만 수정해도 바로 변경 사항이 반영되기 때문에 운영과 유지보수 측면에서 훨씬 효율적입니다.정리하자면, Electron 앱 배포 후에도 React UI를 자유롭게 업데이트할 수 있도록 하기 위해loadURL() + Firebase 배포 방식을 강의에서 사용했습니다. 한 번 직접 React 프로젝트를 npm run build로 정적 파일로 빌드한 뒤,loadFile()을 통해 타이머 앱을 오프라인 환경에서도 실행해보시는 것도 추천드립니다! 말씀하신 주의사항들 외에는 loadFile() 방식에도 크게 문제는 없습니다. 진행 하시면서 문제가 발생하거나 다른 어려움이 있으실 경우 언제든지 문의 바랍니다. 감사합니다!
- 0
- 2
- 29
Q&A
관리자 자동 로그아웃 문의드립니다.
안녕하세요. 늦게 답변을 달아드려서 죄송합니다. Q. 로그인 시 isLoggedIn이 true로 바뀌고, 토큰 만료(24시간) 후 다시 관리자 페이지에 접속하면 자동으로 isLoggedIn이 false로 바뀌게 하고 싶습니다. 하지만 현재 그렇게 되지 않습니다. 어떻게 해결할 수 있을까요?A. 챕터 6-6까지 진행된 코드에서는 JWT 토큰 만료는 클라이언트 측 인증만 무효화할 뿐,MongoDB에 저장된 isLoggedIn 필드는 자동으로 변경되지 않습니다.로그인 시 isLoggedIn = true 로 설정됨 JWT는 expiresIn: "24h" 설정으로 인해 24시간 후 자동 만료됨그러나 백엔드나 DB에는 “토큰 만료됨”이라는 이벤트가 발생하지 않기 때문에isLoggedIn 필드를 false로 되돌릴 코드가 실행되지 않음 결국 DB는 여전히 사용자가 로그인 중(true)인 상태로 남게 됩니다. 해결 방법으로는 모든 관리자 페이지 접근 전에 토큰을 검증하는 미들웨어를 추가하고,토큰이 만료된 경우 해당 사용자의 isLoggedIn을 자동으로 false로 업데이트합니다.백엔드 폴더에 middleware/verifyToken.js 를 생성하고 코드를 작성합니다.// middleware/verifyToken.js const jwt = require("jsonwebtoken"); const User = require("../models/User"); const verifyToken = async (req, res, next) => { const token = req.cookies.token; if (!token) { return res.status(401).json({ message: "토큰이 없습니다." }); } try { const decoded = jwt.verify(token, process.env.JWT_SECRET); req.user = decoded; next(); } catch (error) { if (error.name === "TokenExpiredError") { // 만료된 토큰에서 사용자 정보 추출 const decoded = jwt.decode(token); if (decoded?.userId) { await User.findByIdAndUpdate(decoded.userId, { isLoggedIn: false }); } } return res.status(401).json({ message: "토큰이 만료되었습니다. 다시 로그인해주세요." }); } }; module.exports = verifyToken;만들어진 미들웨어를 실제로 활용하는 방법의 예시입니다.const verifyToken = require("../middleware/verifyToken"); router.get("/admin/dashboard", verifyToken, async (req, res) => { res.json({ message: "관리자 페이지 접속 성공" }); });사용자가 로그인하면 서버는 JWT 토큰을 발급하고 isLoggedIn을 true로 설정합니다.사용자는 이 토큰을 가지고 관리자 페이지 등에 접근할 때마다 요청 헤더 또는 쿠키에 포함시켜 서버로 전송합니다.미들웨어가 매 요청마다 토큰을 검증합니다.토큰이 유효하면 요청을 정상적으로 통과시킵니다.토큰이 만료되었다면 (TokenExpiredError),해당 토큰에서 userId를 추출하고DB에서 해당 사용자의 isLoggedIn을 false로 자동 업데이트합니다.이후 서버는 401 Unauthorized 응답을 보내어 “세션이 만료됨”을 알립니다.클라이언트는 이 응답을 받아 로그인 페이지로 리다이렉트하거나 다시 로그인하도록 처리합니다.추가 질문이 있다면 언제든지 문의 부탁드립니다. 감사합니다!
- 0
- 1
- 29
Q&A
verify_token 함수의 네이밍에 대한 질문입니다
안녕하세요! 세심한 피드백 정말 감사합니다.말씀해주신 부분이 정확합니다. 원래는 verify_token 함수가 토큰의 유효성 검증만 수행하고 Boolean 값을 반환하도록 구현되어 있었는데, 이후 리팩토링 과정에서 검증과 동시에 user id를 반환하는 형태로변경되면서 함수명도 함께 수정했어야 했습니다. 하지만 당시 네이밍을 그대로 두는 바람에 혼란을 드리게 되었습니다.get_uid_from_token이나 extract_user_id처럼 실제 반환 값을 명확히 드러내는 네이밍이 훨씬 직관적이라는 점에 깊이 공감합니다. 현실적으로는 강의 전체를 수정하기는 어려운 상황이지만, 말씀해주신 의견은 매우 합당하고 실무적으로도 중요한 지적입니다.좋은 피드백 주셔서 진심으로 감사드립니다. 이런 세심한 관점이 강의 품질을 개선하는 데 큰 도움이 됩니다.
- 0
- 2
- 32
Q&A
6-2 강의 노션 코드 오타인거죠? 2
안녕하세요, 소중한 의견 남겨주셔서 진심으로 감사합니다.말씀해주신 SingleTopic/Chart/ChartCanvas.jsx (39번 라인)의 stroke={colors[i].bg} 문제를 확인하였고, 강의자료에서 수정하였습니다.귀중한 피드백 덕분에 더 나은 강의를 만들 수 있습니다.시간 내어 알려주셔서 진심으로 감사드립니다.
- 0
- 3
- 36
Q&A
파일명 , 폴더명 대문자 소문자, 케이스 구별법이궁금해요
안녕하세요. 질문 주셔서 감사합니다. Q. 각 폴더에 따라 이름을 짓는 방법이 다른 것 같습니다. 폴더와 파일명 대문자/소문자 규칙이 궁금합니다.이번 프로젝트의 폴더와 파일 명명 규칙은 엄격한 규칙보다는 개인 취향이 반영된 부분이 있습니다.Utils 폴더폴더명은 항상 대문자(Utils)로 시작하고, 안의 파일은 첫 단어는 소문자, 뒤따르는 단어는 첫 글자만 대문자 형식으로 작성합니다.예시:adminLoginUtils.tsxcommunityDetailUtils.tsxcommunityUtils.tsxpredictUtils.tsx이렇게 하면 파일명이 길어져도, 어떤 기능과 역할을 하는 파일인지 직관적으로 알 수 있습니다.Components 폴더 및 하위 폴더폴더와 파일 이름 모두 단어와 상관없이 첫 글자를 대문자로 작성하는 경우가 있습니다.UI 컴포넌트임을 시각적으로 바로 구분할 수 있고, 프로젝트를 처음 보는 사람도 구조를 이해하기 쉽습니다.팀 내 통일성팀에서 파일명을 정할 때, 예를 들어 predict + utils라는 파일을 만들면누군가는 predictUtils라고 하고, 누군가는 PredictUtils라고 할 수 있습니다.이런 차이로 오해가 생길 수 있지만, 실제 기능이나 동작에는 전혀 영향을 주지 않습니다.따라서 질문자님께서 보시기에 보기 편하고 이해하기 쉬운 방식으로 선택하시면 됩니다.정리이번 프로젝트에서 파일명과 폴더명은 PascalCase 및 camelCase 방식을 적절히 혼합해서 사용했습니다.기능별로 구분되어 있어 유지보수나 확장이 쉽고, 다른 개발자가 봐도 직관적으로 이해할 수 있습니다.즉, 엄격한 컨벤션보다 실용성과 편의성을 우선시한 방식이라고 볼 수 있습니다.감사합니다!
- 0
- 1
- 35
Q&A
강의 잘듣고있습니다. next js에서 src 폴더 및에 폴더들 이름 정의할때 첫글자를 대문자로하는 이유가있나요?
안녕하세요. 질문 주셔서 감사합니다. Q1. Next.js에서 src 및 하위 폴더명을 대문자로 쓰는 이유A. 좋은 질문입니다. 예를 들어 src 폴더 안에서 컴포넌트를 관리할 때, components 대신 Components로 쓰는 경우가 있습니다.이건 컨벤션(코드 스타일)의 차이일 뿐, 기능이나 성능에는 전혀 영향이 없습니다.소문자(components)→ 일반적으로 폴더명은 소문자로 시작하는 게 표준적이며, Next.js 공식 문서에서도 이 방식을 따릅니다.대문자(Components)→ 폴더가 컴포넌트를 담고 있음을 시각적으로 강조하기 위한 선택입니다.예를 들어 Components, Pages, Hooks, Utils처럼 역할별 폴더를 명확히 구분하려는 의도입니다.즉, 어느 쪽이든 성능이나 동작상 차이는 없으며,개인 취향이나 팀의 스타일 가이드에 맞춰 통일만 해주시면 됩니다Q2. Next.js 실습 시 사용한 폴더 구조는 어떤 구조이며, 상용화된 구조인가요?A. 이번 프로젝트에서는 Next.js의 기본 구조를 기반으로, 코드를 역할별로 구분하여 관리하기 쉽게 보이기 위한 폴더 구조를 사용했습니다.아래는 현재 사용 중인 폴더 구조입니다.src/ ├── app/ ├── Components/ ├── Hooks/ ├── Utils/ ├── Styles/ ├── Types/ ├── Constants/ └── lib/Next.js는 기본적으로 폴더 구조를 엄격하게 제한하지 않기 때문에, 이처럼 기능별로 구분된 구조는 실무나 팀 프로젝트에서 자주 사용되는 형태입니다. 각 역할이 명확하게 나누어져 있어 유지보수나 확장이 용이하며, 다른 개발자와 협업할 때도 효율적입니다.또한, Next.js로 상용화된 프로젝트는 깃허브에서 찾기 어려운 편이지만, 그 중 대표적인 예로 Appwrite를 들 수 있습니다. Appwrite는 Next.js 기반으로 개발된 오픈소스 백엔드 플랫폼으로,현재 GitHub에서 53K개 이상의 별(⭐) 을 받은 대규모 상용 프로젝트입니다.Appwrite의 코드 구조를 살펴보면, 이번에 사용한 구조와 마찬가지로 기능별로 폴더를 나누어 관리하는 실무 중심의 방식을 채택하고 있습니다.깃허브 주소: https://github.com/appwrite/Q3. Next.js도 Electron으로 포팅할 수 있나요?네, 가능합니다. Electron은 프레임워크에 크게 구애받지 않고 웹 기술로 만든 앱을 데스크톱으로 포팅할 수 있습니다. 비유하자면, Electron은 액자와 같고, 프론트엔드 프레임워크(React, Next.js, Vue 등)는 그 안에 넣는 사진과 같습니다.즉, 어떤 사진을 넣든 액자만 있으면 전시가 가능한 것처럼, Next.js든 React든, 심지어 다른 웹 기술로 만든 앱도 Electron 안에서 실행할 수 있습니다. 질문 주셔서 감사합니다. 즐거운 추석 연휴 잘 보내시고, 남은 명절도 편안하게 마무리하시길 바랍니다.
- 0
- 2
- 39
Q&A
[강의 오류 리포트] React Router Outlet 사용 오류
안녕하세요, 소중한 오류 리포트 남겨주셔서 진심으로 감사드립니다.말씀해주신 React Router Outlet 관련 오류는 확인 후, 문제된 부분을 수정하였습니다. 강의 영상이 업로드 과정에서 임의로 분할되는 과정에서 코드 구조 일부가 누락되어 발생한 문제로 확인되었습니다. 이러한 실수로 인해 학습에 불편을 드린 점 진심으로 사과드립니다.현재 챕터 4의 코드 및 강의 내용을 다시 꼼꼼히 검수하였고, 1~3챕터 또한 검수를 진행하였으며, 이후 챕터들 또한 순차적으로 검수 및 수정 작업을 진행 중입니다. 질 낮은 강의로 실망을 드린 점 매우 죄송하게 생각하며, 더 나은 완성도로 보답드리겠습니다.귀중한 시간 내어 상세히 제보해주셔서 다시 한 번 감사드립니다. 꾸준히 개선하며 신뢰할 수 있는 강의로 만들어가겠습니다. 감사합니다.
- 0
- 1
- 40
Q&A
[강의 오류 제보] Navbar 컴포넌트 코드 오류 발견
안녕하세요, 소중한 오류 제보 정말 감사합니다. 말씀해주신 Navbar 컴포넌트의 logout 관련 부분을 확인해보니, 말씀하신 대로 함수명이 불일치하여 에러가 발생하는 문제가 있었습니다. 꼼꼼히 확인해주신 덕분에 원인을 빠르게 파악하고, 해당 섹션의 강의 자료와 코드를 모두 수정 및 반영했습니다.이처럼 세세하게 살펴보고 정확히 제보해주셔서 정말 감사드립니다. 덕분에 다른 학습자분들도 더 원활하게 학습하실 수 있을 것 같습니다. 앞으로도 자료와 강의 내용을 더욱 꼼꼼히 검수하겠습니다. 감사합니다!(사진)
- 0
- 2
- 40
Q&A
데모사이트 접속이 안됩니다.
안녕하세요. 문의 남겨주셔서 감사합니다.아마도 서버의 Docker가 잠시 중단되어 접속이 안되었던 것 같습니다.현재는 정상적으로 접속 가능합니다. 감사합니다!
- 0
- 1
- 30
Q&A
membership부분은 몇 강의에서 진행하신건가요?
안녕하세요, 질문 주셔서 감사합니다! 말씀하신 멤버십 기능은 섹션 17, Ch.16 (풀스택) – 멤버십 결제 기능 구현 (1부) 에서 진행됩니다.해당 강의에서는 포트원 사이트에서 제공하는 KG이니시스 API를 활용하여 결제 기능을 구현하는 과정을 다루고 있습니다. (사진) 감사합니다!
- 0
- 1
- 32





