묻고 답해요
132만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결따라하며 배우는 HTML, CSS
유튜브 실습
안녕하세요.선생님의 강의를 보고 유튜브 실습을 진행했는데 search bar의 위치가 중앙이 아닌 오른쪽 다른 아이콘에 붙어있습니다.코드를 확인했을때 이상하다고 생각하는 부분이 없었습니다...그리고 sidebar의 글자 크기는 영상과 달라도 괜찮나요?.header{ height: 55px; display: flex; flex-direction: row; justify-content: space-between; position: fixed; top: 0; left: 0; right: 0; z-index: 100; background-color: #212121ff; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #4d4d4d; } .left-section{ display: flex; align-items: center; } .hamburger-menu{ height: 24px; margin-left: 24px; margin-right: 24px; } .youtube-logo{ height: 70px; } .middle-section{ flex: 1; margin-left: 70px; margin-right: 35px; max-width: 500px; display: flex; align-items: center; flex-grow: 1; } .search-bar{ flex: 1; height: 36px; padding-left: 10px; font-size: 16px; border: 1px solid #4d4d4d; border-radius: 2px; background-color: #121212; width: 0; } .search-bar::placeholder{ font-size: 16px; } .search-button{ height: 40px; width: 66px; background-color: #323232; border: 1px solid #4d4d4d; margin-left: -1px; margin-right: 10px; } .search-icon{ height: 25px; } .voice-search-button{ height: 40px; width: 40px; border-radius: 20px; border: none; background-color: #121212; } .voice-search-icon{ height: 24px; } .search-button, .voice-search-button, .upload-icon-container{ display: flex; justify-content: center; align-items: center; position: relative; } .search-button .tooltip, .voice-search-button .tooltip, .upload-icon-container .tooltip{ position: absolute; background-color: white; bottom: -30px; padding: 4px 8px 4px 8px; border-radius: 2px; font-size: 12px; opacity: 0; transition: opacity 0.15s; white-space: nowrap; } .search-button:hover .tooltip, .voice-search-button:hover .tooltip, .upload-icon-container:hover .tooltip{ opacity: 1; } .upload-icon{ height: 24px; } .youtube-apps-icon{ height: 24px; } .notifications-icon{ height: 24px; } .current-user-picture{ height: 32px; border-radius: 16px; } .right-section{ width: 180px; margin-right: 20px; display: flex; justify-content: space-between; align-items: center; } .notifications-icon-container{ position: relative; } .notifications-count{ position: absolute; top: -2px; right: -5px; background-color: rgb(200, 0, 0); color: white; font-size: 11px; padding-left: 5px; padding-right: 5px; padding-top: 2px; padding-bottom: 2px; border-radius: 10px; } <header class="header"> <div class="left-section"> <img class="hamburger-menu" src="assets/icons/hamburger-menu.svg" > <img class="youtube-logo" src="assets/icons/youtube-logo.svg"> </div> <div class="middle-section"> <input class="search-bar" type="text" placeholder="Search" > <button class="search-button"> <img class="search-icon" src="assets/icons/search.svg" > <div class="tooltip">Search</div> </button> <button class="voice-search-button"> <img class="voice-search-icon" src="assets/icons/voice-search-icon.svg" > <div class="tooltip">Search with your voice</div> </button> <div class="right-section"> <div class="upload-icon-container"> <img class="upload-icon" src="assets/icons/upload.svg" > <div class="tooltip">Create</div> </div> <img class="youtube-apps-icon" src="assets/icons/youtube-apps.svg" > <div class="notifications-icon-container"> <img class="notifications-icon" src="assets/icons/notifications.svg"> <div class="notifications-count">1</div> </div> <img class="current-user-picture" src="assets/images/avatars/avatar-1.png" > </div> </div> </header>
-
해결됨[JS] Phaser 게임 제작 - 뱀파이어 서바이벌 클론
npm start 에러코드가 나와 문의드립니다.
3-4 Code Review 챕터에 있는 zip 파일을 다운 받은 후 압축을 풀고 start 시 에러가 나옵니다.에러 로그에 보면 Unexpected character ' '이라고 나오는데수정을 전혀 하지 않은 상태이기 때문에 저런 에러가 나오는 이유를 모르겠습니다. 감사합니다. > phaser3-project-template@1.1.2 start> webpack-dev-server --config webpack/base.js --openi 「wds」: Project is running at http://localhost:8080/i 「wds」: webpack output is served from /i 「wds」: Content not from webpack is served from D:\Apache24\htdocs\game3-2Browserslist: caniuse-lite is outdated. Please run next command npm updatei 「wdm」: wait until bundle finished: /× 「wdm」: Hash: 9cc55ccc66d0b371b405Version: webpack 4.41.2Time: 3283msBuilt at: 2024. 02. 08. 오전 10:36:34 Asset Size Chunks Chunk Namesindex.html 158 bytes [emitted] main.js 18.4 MiB main [emitted] mainEntrypoint main = main.js[0] multi (webpack)-dev-server/client?http://localhost:8080 ./src 40 bytes {main} [built][./node_modules/ansi-html/index.js] 4.16 KiB {main} [built][./node_modules/ansi-regex/index.js] 135 bytes {main} [built][./node_modules/html-entities/index.js] 231 bytes {main} [built][./node_modules/strip-ansi/index.js] 161 bytes {main} [built][./node_modules/webpack-dev-server/client/index.js?http://localhost:8080] (webpack)-dev-server/client?http://localhost:8080 4.29 KiB {main} [built][./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.51 KiB {main} [built][./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.53 KiB {main} [built][./node_modules/webpack-dev-server/client/utils/createSocketUrl.js] (webpack)-dev-server/client/utils/createSocketUrl.js 2.89 KiB {main} [built][./node_modules/webpack-dev-server/client/utils/log.js] (webpack)-dev-server/client/utils/log.js 964 bytes {main} [built][./node_modules/webpack-dev-server/client/utils/reloadApp.js] (webpack)-dev-server/client/utils/reloadApp.js 1.59 KiB {main} [built][./node_modules/webpack-dev-server/client/utils/sendMessage.js] (webpack)-dev-server/client/utils/sendMessage.js 402 bytes {main} [built][./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built][./src/Config.js] 1.16 KiB {main} [built][./src/index.js] 87 bytes {main} [built] + 25 hidden modulesERROR in ./src/scenes/LoadingScene.jsModule build failed (from ./node_modules/babel-loader/lib/index.js):SyntaxError: D:\Apache24\htdocs\game3-2\src\scenes\LoadingScene.js: Unexpected character '' (244:4) 242 | } 243 | }> 244 | | ^ 245 | at Parser.raise (D:\Apache24\htdocs\game3-2\node_modules\@babel\parser\lib\index.js:6930:17) at Parser.getTokenFromCode (D:\Apache24\htdocs\game3-2\node_modules\@babel\parser\lib\index.js:7638:16) at Parser.nextToken (D:\Apache24\htdocs\game3-2\node_modules\@babel\parser\lib\index.js:7150:12) at Parser.next (D:\Apache24\htdocs\game3-2\node_modules\@babel\parser\lib\index.js:7079:10) at Parser.eat (D:\Apache24\htdocs\game3-2\node_modules\@babel\parser\lib\index.js:7084:12) at D:\Apache24\htdocs\game3-2\node_modules\@babel\parser\lib\index.js:11386:20 at Parser.withTopicForbiddingContext (D:\Apache24\htdocs\game3-2\node_modules\@babel\parser\lib\index.js:10486:14) at Parser.parseClass (D:\Apache24\htdocs\game3-2\node_modules\@babel\parser\lib\index.js:11359:22) at Parser.parseExportDefaultExpression (D:\Apache24\htdocs\game3-2\node_modules\@babel\parser\lib\index.js:11779:19) @ ./src/Config.js 1:0-49 12:10-22 @ ./src/index.jsChild html-webpack-plugin for "index.html": 1 asset Entrypoint undefined = index.html [./node_modules/html-webpack-plugin/lib/loader.js!./index.html] 313 bytes {0} [built] [./node_modules/lodash/lodash.js] 528 KiB {0} [built] [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {0} [built] [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]i 「wdm」: Failed to compile. - 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
해결됨Vue3 완벽 마스터: 기초부터 실전까지 - "기본편"
vue3+ cli로 구성해도 강의 따라가기에 문제가 없나요?
안녕하세요 짐코딩님!혹시 vue3 + cli 조합으로 해도 강의 따라가기에 문제가 없을까요...??회사 서버 상황상 vue3+ vite 가 불가능할 것 같은데, cli 조합으로 vue3를 배우려고 하면 짐코딩님 강의를 수강하면 안되는 것일지 궁금합니다!ㅠㅠ
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
[프로젝트 실행하는 법] for 스프링 부트 3.2 이상 자바 버전 17 이상
start.spring.io 가서 새로 만드시는 게 더 편합니다. Group : helloartifact item-servicepackage name : hello.itemservicepackaging : JarDependencies- Spring Web- Thymeleaf- Lombok그리고 form-start에서 main하고 test 폴더 그대로 복붙하시면 유일하게 한곳에서 에러 뜹니다. 아마 TestDataInit 에서 에러뜨는데 import javax.annotation.PostConstruct;-> import jakarta.annotation.PostConstruct;이렇게 변경하세요 그럼 끝
-
미해결가장 빠른 풀스택: 파이썬 백엔드와 웹기술 부트캠프 (flask/플라스크와 백엔드 기본) [풀스택 Part1-1]
혹시 강의자료 공유가 가능한가요?
강의자료가 공유가 가능하신지 문의 드립니다. 코드위주로만 작성하다보니, 설명해주신 텍스트를 작성하는게 부족했는데, 강의 처음부터 다시 작성하자니 시간이 너무 오래걸릴것 같아 여쭤보기 위해 질문글 남깁니다. 강의 자료가 가능하신지 확인해주시면 감사하겠습니다.
-
미해결구글 애드센스 수익형 워드프레스 블로그 만들기
워프 설치 전 문의드립니다
안녕하세요~ 카페 24로 호스팅했다가 제한이 많이 강의내용 따라가기가어려워 다시 패스트코멧으로 호스팅을했습니다. 도메인도 호스팅케이알에서 받아 진행을하고, 이제 30시간 넘어 지났는데요 아직도 도메인 접근하면 호스팅이 연결이 되지않은것 같아, 강의보기를 더 진행을 못하고있습니다.혹시 도메인 연결되기전에 미리 워프를 설치하고 강의내용을 따라 설정을 해도 되나요? 아니면 다른 방법으로 진행하고, 나중에 다른 변경설정을 해야되는지 알고싶습니다. 설 연휴다보니.. 테마를 요청드리고 빨리 받아서 적용을 하고싶어서^^;; 문의드립니다. 감사합니다 : )
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
4:40초에 하시는 말씀(findMember 호출한 곳)
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]영한쌤께서 4분40초쯤에 하시는 말씀 중 findMember 호출한 데가 없다고 말씀하시는데, 그게 무슨 말인가요..? join은 예제에서 잘 호출됐는데... 하신 말씀이 잘 이해가 안 가서 질문드립니다!
-
미해결[초급] 찍어먹자! 코틀린과 Spring Security + JWT로 회원가입 만들기
Next Lv 강의에 대해서 계획중이신게 있을까요?
LDAP나 OAuth2는 다른거하고 연동하는거니까 패스하고.. Method Security(PreAuthorize, PostFilter, etc...)Role HierarchyLow Level Security(privileges) - Read, Write, Update, Delete등등 이런 고급 시큐리티쪽이요!
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
multipartfile 리스트
안녕하세요. 스프링 개발할 때 질문이 있어서 글을 쓰게 되었습니다. 프론트에서 게시글관련 정보와 multipartfile 리스트를 넘겨주는 api를 만들고 있습니다. 만약 multipartfile 리스트를 안넘겨줘도 문제가 없는 요구사항이라면 multipartfile 리스트가 null이나 빈파일을 포함하고 있는지 확인하는 로직은 어디다가 놓는 것이 좋을까요?(빈파일은 size가 0인 multipartfile) 현재는 requestDto 생성자에서 검사하고 있습니다.null이면 빈리스트를 넣도록하고그 다음에 빈파일을 포함하고 있으면 빈파일들을 필터링하게 만들었습니다.
-
미해결카프카 완벽 가이드 - ksqlDB
전통적 분석 시스템 한계에 대해 질문있습니다.
안녕하세요, 실시간 분석 시스템 아키텍처에 ksqlDB 사용 명분(?)을 좀 더 확실히 하고 싶어서 질문드립니다. 제가 이해한 것은 전통적 분석 시스템은 운영 DB 부하로 분석 시스템을 직접 붙일 수 없고, DW/Batch을 분석용으로 따로 두는 것으로 이해했습니다.운영계에서 DW로 데이터를 전송하는 주기가 하루 주기인 것도 마찬가지로 운영계 I/O 부하 문제인걸까요? 또한 실시간 분석 시스템의 경우 CDC를 통해 일단위 데이터 전송에서 실시간으로 전송이 가능한 것으로 보이는데 이것은 redo dump file 전송은 DB에 직접적인 부하를 주지 않기 때문에 가능한 것인가요? 마지막으로 CDC 기반으로 실시간 데이터 전송을 했을 때 타겟 DBMS가 좋은 퍼포먼스를 가져야 함은 실시간 데이터에 대한 부하를 견딜 수 있어야 하기 때문인건가요? 질문이 많네요.. 늘 좋은 강의 감사드립니다.
-
미해결Vue3 완벽 마스터: 기초부터 실전까지 - "실전편"
form 태그에 이벤트 발생시 작동하지 않는건에 대해
질문은 아니고~ 수업을 진행하다 form @submit.prevent="함수명"해당 부분이 작동하지 않아(아예 무반응) button태그에 실행 함수를 넣으니 잘 작동하여 form 문제인거 같아 확인해보니 form안에 button이 존재할 경우 발생하는 문제였네요.form 태그안에 @submit.prevent="함수명" 은 유지하고버튼에 @click.self.prevent="함수명"을 넣으면 됩니다. 동일 문제가 발생하신다면 진행해 보세요.
-
미해결Vue 3 시작하기
defineProps, defineEmit, defineModel 차이
부모와 자식 컴포넌트간의 데이터 교환에 있어부모 -> 자식 : props자식 -> 부모 : emit이라는건 어느정도 개념이 잡힌 것 같습니다. 근데, 좀 더 찾아보니 부모자식 컴포넌트 사이에도 model을 지정해서 양방향 바인딩이 가능하다는 예제를 본 것 같습니다. model을 사용하여 props & emit을 대체한다면 복잡한 코드가 좀 더 나아질것 같은데 defineModel을 사용하지 않는 이유가 따로 있는것일까요?
-
미해결스프링 핵심 원리 - 기본편
Autowired members must be defined in valid Spring bean
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.@Autowired 를 명시했을 때 Autowired members must be defined in valid Spring bean (@Component|@Service|...)에러가 발생합니다. 해당 에러를 조사해보니 의존성 주입을 받는 클래스가 스프링 빈으로 등록되지 않았을 때 혹은 정의된 빈이 스프링 컨테이너에 의해 관리되지 않는 경우 에 발생한다고 하는데, Q1.명시하지않았을 때는 정상적으로 수행되는데, 명시했을 때 위문제가 발생하는 이유가 궁금합니다. Q2.@Autowired 를 명시했을 때는 다른 에노테이션들도 다 명시해야 되는건가요?
-
미해결따라하며 배우는 리액트 A-Z
오류메세지는 확인했는데 어떻게 고쳐야 할지 모르겠습니다 ㅠ
TODO앱을 클래스앱에서 컴포넌트 함수형 으로 바꾸는과정에서 뭔가 문제가 생겼는지 아니면 이전부터 문제가 있었는지는 모르겠는데 이런오류가 뜨면서 되지않네요 ㅠㅠ 리액트 초짜라 뭘 어떻게 바꿔야할지 모르겠습니다 ㅠㅠ 답변부탁드립니다 감사합니다 ㅠㅠ위에 문제가 된다고 하는 6행 74행 사진입니다 ㅠㅠ
-
해결됨Go Hard to Unreal (feat. 취준 멘토링)
강의 리메이크 관련 질문입니다.
강의가 리메이크 된다고 하는데 그러면 리메이크 되고나서 강의를 듣는게 좋을까요?아니면 기존 강의 계속 듣는게 좋을까요?그리고 기존 강의 교재 내용이 없어졌는데 리뉴얼 중인가요? 확인 한번 부탁 드릴게요.
-
해결됨실전! FastAPI 입문
DATABASE_URL 상수변수 질문
도커를 이용해 컨테이너를 실행시킬 때 root 사용자에 대해서 todos라는 비밀번호를 갖도록 설정을 해주었는데, DATABASE_URL = "mysql+pymysql://root:todos@127.0.0.1:3306/todos"상수 변수를 이용해 데이터베이스 연결 시도 시,(1045, "Access denied for user 'root'@'localhost' (using password: YES)") 이런 에러가 발생합니다.비밀번호를 설정하였는데도 왜 이렇게 발생하는 건가요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
result를 Optional<Member>로 선언하지 않는 이유
[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요. MemoryMemberRepositoryTest 파일에 대한 질문이 있습니다.public void findAll() {} 에서 보시면 result를 List<Member>로 선언해줬는데,public void findByName(){} 에서는 result를 Optional<Member>로 선언하지 않는 이유가 궁금합니다...MemoryMemberRepository 파일의 메소드와 동일하게 가려면 맞춰줘야 하는 줄 알았는데 Member result로만 선언이 되길래 여쭤봅니다!
-
해결됨홍정모의 따라하며 배우는 C++
9.12 강의 마지막에 내주신 숙제가 잘 이해가 안갑니다.
대입연산자를 오버로딩 해보라고 말씀하셨는데 대입연산자를 이용해서 이니셜라이저리스트로 클래스를 생성해보란 말씀이신가요? 근데 그건 이미 교수님이 강의 마지막에 되는걸 보여주신거 아닌가요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
새로 고침 시 로그인이 유지되지 않는 버그가 발생합니다!(쿠키 존재O)
안녕하세요 제로초님!AWS에 배포하기 및 카카오톡 공유하기 강의까지 끝마친 수강생 입니다!저는 윈도우 10, 크롬 브라우저, VSCode, MySQL 8버전을 사용하고 있습니다.로그인 후 새로 고침을 하면 로그인이 유지되지 않고 풀려 버리는 버그가 발생하여질문을 올리게 되었습니다! 이 문제는 쿠키가 있음에도 발생합니다!이 버그로 인해 총 2가지 상태에 이릅니다.1. 완전히 로그인을 한 상태에서 새로 고침을 하면 쿠키는 남아있으나 로그인이 유지되지 않습니다.2. 완전히 로그인이 된 상태에서 프로필 페이지로 이동하면 로그인이 풀리며 홈페이지로 돌아옵니다.새로 고침 후 로그인이 풀리는 문제가 발생한 시점에서다시 로그인을 하려고 하면 로그인 유무 검사(로그인하지 않은 사용자만 접근 가능) 메시지가 뜹니다.로그인 후 로그아웃을 하면 해당 문제가 발생하지 않습니다.해당 에러를 임시로 해결하는 방법을 찾았습니다.프론트 페이지와 백엔드 페이지 애플리케이션 탭에서 쿠키를 지우면 다시 로그인을 진행할 수 있습니다. 하지만 말 그대로 임시로 해결하는 것 뿐이라 로그인 후 새로 고침을 하면아까와 똑같이 로그인이 풀려버립니다.문제를 해결하기 위해 페이지에서 콘솔 탭과 네트워크 탭, 애플리케이션 탭의 쿠키 쪽을 확인하였습니다.프론트 콘솔 탭 확인해당 에러 주소로 들어가 보았지만 외계어로 적혀있어 다른 곳을 먼저 확인해보기로 했습니다.프론트 네트워크 탭 확인401 Unauthorized 에러를 네트워크 탭에서 확인 했습니다.Headers 탭에 적힌 쿠키와 Cookies 탭에 적힌 쿠키는 똑같았습니다!프론트 쿠키 존재 확인로그인 후 로그아웃을 진행하면 쿠키가 남아있습니다. 백엔드 쿠키 존재 확인백엔드 페이지도 프론트 쪽과 똑같이 쿠키가 잘 들어가 있음을 확인하였습니다.페이지 쪽을 전부 확인한 뒤, 우분투 백엔드 pm2 monit을 확인해보니사용자 로그인 쪽에서 401 에러가 나고 있었습니다.sudo npx pm2 logs --err --lines 200 명령어로 에러 로그를 확인하였으나관련 에러는 찾지 못하였습니다.문제를 해결하기 위해 잘못 적은 코드가 있는지 검사하였습니다.아래는 가장 의심되는 코드들 입니다!리듀서, 사가, 라우터, 로그인 검사, 서버사이드 렌더링 순으로 작성하였습니다.front/reducers/user.js나의 사용자 정보 불러오기 리듀서const reducer = (state = initialState, action) => { return produce(state, (draft) => { switch (action.type) { /* 나의 사용자 정보 불러오기 요청 리듀서 */ case LOAD_MY_INFO_REQUEST: draft.loadMyInfoLoading = true; draft.loadMyInfoError = null; draft.loadMyInfoDone = false; break; /* 나의 사용자 정보 불러오기 성공 리듀서 */ case LOAD_MY_INFO_SUCCESS: draft.loadMyInfoLoading = false; draft.me = action.data; draft.loadMyInfoDone = true; break; /* 나의 사용자 정보 불러오기 실패 리듀서 */ case LOAD_MY_INFO_FAILURE: draft.loadMyInfoLoading = false; draft.loadMyInfoError = action.error; break;로그인 리듀서. . . /* 로그인 요청 리듀서 */ case LOG_IN_REQUEST: draft.logInLoading = true; draft.logInError = null; draft.logInDone = false; break; /* 로그인 성공 리듀서 */ case LOG_IN_SUCCESS: draft.logInLoading = false; draft.me = action.data; // 로그인 성공 시 실제 사용자 데이터 draft.logInDone = true; break; /* 로그인 실패 리듀서 */ case LOG_IN_FAILURE: draft.logInLoading = false; draft.logInError = action.error; break; front/sagas/user.js나의 사용자 정보 불러오기 사가// loadMyInfo 실행 시 서버에 loadMyInfoAPI 요청 function loadMyInfoAPI() { return axios.get('/user'); } // LOAD_MY_INFO 액션이 실행되면 loadMyInfo 함수 실행 function* loadMyInfo(action) { /* 요청 성공 시 LOAD_MY_INFO_SUCCESS 액션 디스패치 */ try { const result = yield call(loadMyInfoAPI, action.data); yield put({ type: LOAD_MY_INFO_SUCCESS, data: result.data, }); /* 요청 실패 시 LOAD_MY_INFO_FAILURE 액션 디스패치 */ } catch (err) { console.error(err); yield put({ type: LOAD_MY_INFO_FAILURE, error: err.response.data, // 실패 결과 }); } }로그인 사가// logIn 실행 시 서버에 logInAPI 요청 function logInAPI(data) { return axios.post('/user/login', data); } // LOG_IN_REQUEST 액션이 실행되면 logIn 함수 실행 function* logIn(action) { /* 요청 성공 시 LOG_IN_SUCCESS 액션 디스패치 */ try { const result = yield call(logInAPI, action.data); yield put({ type: LOG_IN_SUCCESS, data: result.data, // 성공 결과 : 서버로부터 사용자 정보를 받아옴 }); /* 요청 실패 시 LOG_IN_FAILURE 액션 디스패치 */ } catch (err) { console.error(err); yield put({ type: LOG_IN_FAILURE, error: err.response.data, // 실패 결과 }); } }back/routes/user.js브라우저 새로 고침 시 나의 사용자 정보를 복구하는 라우터나의 사용자 정보를 복구하는 라우터는 user 라우터들 중에서 제일 위에 위치합니다!// 브라우저 새로고침 시 나의 사용자 정보를 복구하는 라우터 router.get('/', async (req, res, next) => { // GET /user // req.headers 안에 쿠키가 들어있다. console.log(req.headers, "req.headers 안에는 쿠키가 들어있다."); try { /* (로그인해서) 사용자 정보가 있다면 */ if (req.user) { /* (비밀번호를 제외한) 모든 사용자 정보를 가져오는 함수 */ const fullUserWithoutPassword = await User.findOne({ where: { id: req.user.id }, attributes: { exclude: ['password'] }, // 모델 가져오기 include: [{ /* 나의 게시글 */ model: Post, attributes: ['id'], // id 데이터만 가져오기 }, { /* 나의 팔로잉 */ model: User, as: 'Followings', attributes: ['id'], }, { /* 나의 팔로워 */ model: User, as: 'Followers', attributes: ['id'], }] }); // 200번대 에러 출력 res.status(200).json(fullUserWithoutPassword); /* (로그아웃해서) 사용자 정보가 없다면 */ } else { // 아무것도 보내지 않기 res.status(200).json(null); } /* 에러 캐치 */ } catch (error) { console.error(error); next(error); } });로그인 라우터// 로그인 라우터 : 사용자 로그인 전략 실행 router.post('/login', isNotLoggedIn, (req, res, next) => { /* '로컬', (서버 에러, 성공 객체, 클라이언트 에러)가 전달 */ passport.authenticate('local', (err, user, info) => { // done에서 넣은 값들이 순서대로 전달되는 곳 /* 서버 에러 */ if (err) { console.error(err); // 콘솔 창을 통한 에러 메시지 출력 return next(err); // 에러 처리 미들웨어로 이동 } /* 클라이언트 에러 : 로그인하다 에러가 나면 클라이언트로 응답 보내기 */ if (info) { return res.status(401).send(info.reason); } /* 로그인 성공 객체 */ return req.login(user, async (loginErr) => { // 서비스 로그인이 끝난 후 패스포트 로그인 할 때 에러발생 시 처리 if (loginErr) { console.error(loginErr); return next(loginErr); } /* (비밀번호를 제외한) 모든 사용자 정보를 가져오는 함수 */ const fullUserWithoutPassword = await User.findOne({ where: { id: user.id }, attributes: { exclude: ['password'] }, // 전체 데이터에서 비밀번호만 제외 // 모델 가져오기 include: [{ /* 나의 게시글 */ model: Post, attributes: ['id'], // id 데이터만 가져오기 }, { /* 나의 팔로잉 */ model: User, as: 'Followings', attributes: ['id'], }, { /* 나의 팔로워 */ model: User, as: 'Followers', attributes: ['id'], }] }); /* (비밀번호를 제외한) 모든 사용자 정보를 프론트로 넘기기 */ return res.status(200).json(fullUserWithoutPassword); }); })(req, res, next); // 미들웨어 커스터마이징 });back/routes/middlewares.js로그인 검사// (로그인 안했을 때) 로그인 유무 검사 exports.isNotLoggedIn = (req, res, next) => { if (!req.isAuthenticated()) { next(); } else { res.status(401).send('로그인하지 않은 사용자만 접근 가능합니다.'); } }; 문제 해결을 위해 노드버드 커뮤니티에서 저와 비슷한 에러가 발생한 수강생 분이 계셨습니다!https://www.inflearn.com/questions/368573/%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%A7%88%EB%AC%B8-%EB%A1%9C%EA%B7%B8%EC%9D%B8%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EC%82%AC%EC%9A%A9%EC%9E%90%EB%A7%8C-%EC%A0%91%EA%B7%BC%EC%9D%B4-%EA%B0%80%EB%8A%A5%ED%95%A9%EB%8B%88%EB%8B%A4해당 글에서 제로초님은 쿠키가 있는 걸로 봐서 이미 로그인이 된 상태인데프론트에서 자신이 로그인 되었다는 것을 인식하지 못하고 있으며,해당 getServerSideProps 쪽에 문제가 있다고 힌트를 주셨습니다!제로초님의 노드버드Ch7 user/[id].jshttps://github.com/ZeroCho/react-nodebird/blob/master/ch7/front/pages/user/[id].jsfront/pages/user/[id].js강의를 진행하며 깃허브와 약간은 다른 코드가 있습니다.// 서버사이드 렌더링(SSR) : getServerSideProps 사용 /* 사용자 컴포넌트보다 먼저 실행, 매개변수 context 안에 store가 들어있다. */ export const getServerSideProps = wrapper.getServerSideProps(async (context) => { /* 변수 cookie에 모든 cookie 정보 저장 */ const cookie = context.req ? context.req.headers.cookie : ''; /* 쿠키를 안 써서 요청 보낼 때는 서버에서 공유하고 있는 쿠키를 제거하기 */ axios.defaults.headers.Cookie = ''; /* 서버일 때, 그리고 쿠키가 있을 때만 서버로 쿠키 전달하기 */ if (context.req && cookie) { // 실제로 쿠키를 써서 요청을 보낼 때만 잠깐 쿠키를 넣어 놓는다. axios.defaults.headers.Cookie = cookie; } /* 처음에 화면을 로딩하면 특정 사용자의 게시글 불러오기 요청 액션 객체 디스패치 */ context.store.dispatch({ type: LOAD_USER_POSTS_REQUEST, data: context.params.id, // 또는 context.query.id로 useRouter에 접근 가능 }); /* 처음에 화면을 로딩하면 나의 사용자 정보 불러오기 요청 액션 객체 디스패치 */ context.store.dispatch({ type: LOAD_MY_INFO_REQUEST, }); /* 처음에 화면을 로딩하면 다른 사용자 정보 불러오기 요청 액션 객체 디스패치 */ context.store.dispatch({ type: LOAD_USER_REQUEST, data: context.params.id, // 또는 context.query.id로 useRouter에 접근 가능 }); /* 나의 사용자 정보, 다른 사용자 정보 불러오기, 여러 게시글 불러오기 요청(REQUEST)이 성공(SUCCESS)으로 바뀔 때까지 기다리기 */ context.store.dispatch(END); await context.store.sagaTask.toPromise(); console.log('getState', context.store.getState().post.mainPosts); return { props: {} }; });리듀서, 사가, 그리고 해당 서버사이드 렌더링 쪽을 점검해보았으나 잘못된 점을 찾지 못하여 질문 남깁니다..어떻게 하면 사용자(나)의 로그인이 유지되게 할 수 있을까요? 혹시 힌트 키워드라도 주실 수 있을까요?긴 질문 글 읽어주셔서 감사합니다 제로초님 항상 강의 잘 보고 있습니다!
-
미해결포토샵 기본기 하루 5분, 3주 만에 끝내기
이수증이나 수료증 발급 가능한가요
제목과 같은 질문입니다