묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[2025년 출제기준] 웹디자인기능사 실기시험 완벽 가이드
A3 크로스페이드 슬라이드가 이상합니다.
저만 그런건지는 모르겠으나, 세번째 슬라이드 이미지가 고정된 상태에서 첫번째, 두번째 슬라이드 이미지가 빠르게 점멸한 뒤 크로스페이드 슬라이드가 시작합니다. 혹시 뭐가 문제일까요?(제일 아래쪽에 코드 텍스트 있습니다.) @charset "utf-8"; body{ margin: 0; font-size: 15px; background-color: #fff; color: #333333; } a{ text-decoration: none; color: #333333; } .container{ border: 1px solid red; width: 1200px; margin: auto; } header{ background-color: rgb(150, 167, 236); height: 100px; } header div{ /* border: 1px solid blue; */ height: 100px; } .header-logo{ width: 200px; float: left; } .navi{ width: 600px; float: right; } .slide{ width: 1200px; height: 300px; position: relative; overflow: hidden; } .slide-items{ position: relative; } .slide-item{ position: absolute; top: 0; left: 0; } .slide div{ /* border: 1px solid green; */ height: 300px; } .items{ overflow: hidden; } .items div{ border: 1px solid violet; box-sizing: border-box; float: left; height: 200px; } .notice{ width: 500px; } .banner{ width: 350px; } .direct{ width: 350px; } footer{ background-color: rgb(222, 222, 222); overflow: hidden; } footer>div{ /* border: 1px solid salmon; */ height: 100px; float: left; box-sizing: border-box; } /*여기서부터는 일부분만 선택해서 적용하는거라 반드시 꺽쇠를 써야함!*/ .footer-logo{ width: 200px; } .footer-menu{ width: 1000px; } .footer-menu div{ /* border: 1px solid blueviolet; */ height: 50px; } /*모듈 이외 부분*/ .header-logo, .footer-logo{ text-align: center; line-height: 130px; } .footer-menu{ text-align: center; padding-top: 15px; } .footer-menu>div a{ padding: 10px; } .banner a>img, .direct a>img{ width: 350px; height: 200px; }ㅡㅡㅡㅡㅡㅡㅡㅡㅡ<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="css/stylesheet.css"> <script src="js/jquery-1.12.4.js"></script> <script src="js/custom.js"></script> <title>A3</title> </head> <body> <div class="container"> <header> <div class="header-logo"> <a href="#"> <img src="img/headerlogo.png" alt="header-logo"> </a> </div> <div class="navi"></div> </header> <div class="slide"> <div class="slide-items"> <a class="slide-item" href="#"> <img src="img/slide1.png" alt="slide1"> </a> <a class="slide-item" href="#"> <img src="img/slide2.png" alt="slide2"> </a> <a class="slide-item" href="#"> <img src="img/slide3.png" alt="slide3"> </a> </div> </div> <div class="items"> <div class="notice"></div> <div class="banner"> <a href="#"> <img src="img/banner.jpg" alt="banner"> </a> </div> <div class="direct"> <a href="#"> <img src="img/direct.png" alt="direct"> </a> </div> </div> <footer> <div class="footer-logo"> <a href="#"> <img src="img/footerLogo.png" alt="footer-logo"> </a> </div> <div class="footer-menu"> <div> <a href="#"> 하단메뉴1 </a> <a href="#"> 하단메뉴2 </a> <a href="#"> 하단메뉴3 </a> </div> <div> COPYRIGHTⓒ by WEBDESIGN. ALL RIGHTS RESERVED </div> </div> </footer> </div> </body> </html>@charset "utf-8"; body{ margin: 0; font-size: 15px; background-color: #fff; color: #333333; } a{ text-decoration: none; color: #333333; } .container{ border: 1px solid red; width: 1200px; margin: auto; } header{ background-color: rgb(150, 167, 236); height: 100px; } header div{ /* border: 1px solid blue; */ height: 100px; } .header-logo{ width: 200px; float: left; } .navi{ width: 600px; float: right; } .slide{ width: 1200px; height: 300px; position: relative; overflow: hidden; } .slide-items{ position: relative; } .slide-item{ position: absolute; top: 0; left: 0; } .slide div{ /* border: 1px solid green; */ height: 300px; } .items{ overflow: hidden; } .items div{ border: 1px solid violet; box-sizing: border-box; float: left; height: 200px; } .notice{ width: 500px; } .banner{ width: 350px; } .direct{ width: 350px; } footer{ background-color: rgb(222, 222, 222); overflow: hidden; } footer>div{ /* border: 1px solid salmon; */ height: 100px; float: left; box-sizing: border-box; } /*여기서부터는 일부분만 선택해서 적용하는거라 반드시 꺽쇠를 써야함!*/ .footer-logo{ width: 200px; } .footer-menu{ width: 1000px; } .footer-menu div{ /* border: 1px solid blueviolet; */ height: 50px; } /*모듈 이외 부분*/ .header-logo, .footer-logo{ text-align: center; line-height: 130px; } .footer-menu{ text-align: center; padding-top: 15px; } .footer-menu>div a{ padding: 10px; } .banner a>img, .direct a>img{ width: 350px; height: 200px; }$('.slide-item:gt(0)').hide(); setInterval(function(){ $('.slide-item:first-child').fadeOut(500).next().fadeIn(500); $('.slide-item:first-child').appendTo('.slide-items'); }, 3000);
-
미해결[2025년 출제기준] 웹디자인기능사 실기시험 완벽 가이드
웹디자인기능사 슬라이드를 이미지로 처리해도 문제없나요?
슬라이드 영역의 텍스트 부분도 주는 것으로 알고 있습니다.그래서 코딩으로 텍스트를 띄우지 않고 포토샵에서 슬라이드의 텍스트와 슬라이드 이미지 합쳐서 저장한 뒤 코딩하는 방식으로 처리해도 감점은 없겠죠?
-
해결됨[말 한마디로 뚝딱!] AI와 함께 나만의 수익화 웹사이트를 만드는 법
화면이 끊겨서 어지러워요
마우스 스크롤이 뚝뚝 끊기며 움직여서 다음번 강의때는 부드럽게 움직이면 좋겠어요... 다음번 강의도 끊기면 보다가 환불할것같네요 중간중간 설명이 생략되어서, 변수가 발생했을때 초보자들에게는 답답하게 느껴질수있을것같아요. 개발자분들에게는 당연하게 느껴질만한 부분들이겠지만,"ai로 코드 한줄 없이"가 강의의 지향점이니까 조금 더 쉽게느껴지도록 설명들을 해주시면 더욱 좋을것같아요강의 주제와 커리큘럼은 너무 좋습니다!
-
미해결[2025년 출제기준] 웹디자인기능사 실기시험 완벽 가이드
display:none 적용 안됨 문제
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>index</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="container"> <div class="main-content"> <div class="left"> <header> <div class="header-logo"></div> <div class="nav"> <ul class="menu"> <li> <a href="#none">메뉴</a> <div class="sub-menu"> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> </div> </li> <li> <a href="#none">메뉴</a> <div class="sub-menu"> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> </div> </li> <li> <a href="#none">메뉴</a> <div class="sub-menu"> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> </div> </li> <li> <a href="#none">메뉴</a> <div class="sub-menu"> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> <a href="#none">서브메뉴</a> </div> </li> </ul> </div> <div class="spot-menu"></div> </header> </div> <div class="right"> <div class="slide"> <div class="slide-image"></div> <div class="slide-banner"></div> </div> <div class="items"> <div class="shortcut"></div> <div class="news-gallery"></div> </div> </div> </div> <footer> <div class="footer-logo"></div> <div class="footer-content"> <div class="footer-link"></div> <div class="copyright"></div> </div> </footer> </div> <script src="script/jquery-1.12.4.js"></script> <script src="script/custom.js"></script> </body> </html>@charset "utf-8"; body { margin: 0; background: white; color: #333; } a { text-decoration: none; color: inherit; } /* entire layout */ .container {} .main-content { display: flex; } .main-content > div { /* height: 800px; */ border: 1px solid #000; } .left { width: 200px; } .right { flex: 1; } /* header */ header { z-index: 999; position: relative; } header > div { border: 1px solid #f00; } .header-logo { height: 100px; } /* 네비 */ .nav { width: 95%; margin: 20px auto; } .menu { list-style: none; padding: 0; margin: 0; } .menu > li { position: relative; } .menu div { display: inline-block; } .menu > li > a { transition: 0.5s; border: 1px solid #000; display: block; text-align: center; padding: 10px; } .menu > li:hover > a { background: #00000050; color: white; } .sub-menu { border: 1px solid #000; display: none; background: #00000050; width: calc(100vw - 200px); top: 0; left: 100%; position: absolute; padding: 6px; } .sub-menu > a { transition: 0.5s; padding: 5px; cursor: pointer; text-align: center; width: 120px; color: white; display: inline-block; } .sub-menu a:hover { color: white; background: #00000060; } /* 네비 */ .spot-menu { height: 50px; } /* slide */ .slide { position: relative; height: 400px; } .slide > div { border: 1px solid #0f0; } .slide-image { height: inherit; } .slide-banner { top: 0; right: 0; width: 150px; height: 300px; position: absolute; } /* news-gallery */ .items {} .items > div { border: 1px solid #000; } .news-gallery { height: 250px; } /* shortcut */ .shortcut { height: 200px; } /* footer */ footer { display: flex; } footer > div { height: 120px; border: 1px solid #000; } .footer-logo { width: 200px; } .footer-content { flex:1; } .footer-content > div { border: 1px solid #0f0; height: 50%; box-sizing: border-box; }$('menu li').mouseenter(function(){ $('.sub-menu').stop().fadeIn() }) $('menu li').mouseleave(function(){ $('.sub-menu').stop().fadeOut() })D유형 메가메뉴 제작중서브메뉴가 display:none으로 없어지지 않는 문제가 생겼습니다.!important 로 적용하면 없어지긴 하는데 제이쿼리가 안먹네요 혹시 어떤 부분이 잘못된걸까요?
-
미해결핵심만 골라배우는 CSS3
css 지정시 class 네이밍에 대해 질문이 있습니다.
안녕하세요. 강의 잘 보고 있습니다. 심플 배너 해설 영상을 보고 있는데 css class 명이 어떨때는 banner-bg 이런식이고 어떤때 에는 cousre__txt 이런식으로 네이밍을 지으시는 것 같은데 권장되는 규칙같은게 있는 건가요??
-
미해결HTML+CSS+JS 포트폴리오 실전 퍼블리싱(시즌1)
Part 1 영상 안나옵니다
[완성본 미리보기] HTML+CSS 실전 퍼블리싱 제작(Part 1)계속 새로고침하고 나갔다 다시들어왔는데 우선 파트2는 나오는데 1이 안나옵니다
-
미해결[2025년 출제기준] 웹디자인기능사 실기시험 완벽 가이드
E유형 slide 높이 질문
E유형 수강중 궁금한점이 생겨 질문드립니다.<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>index</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <div class="main-content"> <div class="left"> <header> <div class="header-logo"></div> <div class="nav"></div> <div class="spot-menu"></div> </header> </div> <div class="center"> <div class="shortcut"></div> <div class="news"></div> <div class="gallery"></div> <div class="banner"></div> </div> <div class="right"> <div class="slide-image"></div> </div> </div> <footer> <div class="footer-logo"></div> <div class="footer-content"> <div class="footer-link"></div> <div class="copyright"></div> </div> </footer> </div> </body> </html>@charset "utf-8"; body { margin: 0; background: #fff; color: #333; } a { text-decoration: none; color: inherit; } /* entire */ .container {} .main-content { display: flex; } .main-content > div { /* height: 800px; */ border: 1px solid #000; } .left { width: 200px; } .center { width: 400px; } .right { flex: 1; } /* header */ header {} header > div { border: 1px solid #000; } .header-logo { height: 100px; } .nav { height: 400px; } .spot-menu { height: 50px; } /* items */ .center > div { border: 1px solid #000; } .shortcut { height: 150px; } .news { height: 300px; } .gallery { height: 300px; } .banner { height: 150px; } /* slide */ .slide-image { border: 1px solid red; height: calc(100vh - 120px); width: inherit; } /* footer */ footer { display: flex; } footer > div { border: 1px solid #000; height: 120px; } .footer-logo { width: 200px; } .footer-content { flex: 1; } .footer-content > div { height: 50%; border: 1px solid #000; box-sizing: border-box; }사진과 같이 슬라이드 밑에 120px 여백이 생기는데 혹시 어떤 부분을 수정해야 정상적으로 나올까요?
-
해결됨[말 한마디로 뚝딱!] AI와 함께 나만의 수익화 웹사이트를 만드는 법
(해결)DBeaver 연결 과정에서 질문 있습니다
DBeaver 연결과정에서 database를 gnuboard로 하고 연결 성공하였는데 tables에 아무 것도 안 뜨는데 어떻게 어떤 것이 잘못됐는지 알 수 있을까요?
-
해결됨[말 한마디로 뚝딱!] AI와 함께 나만의 수익화 웹사이트를 만드는 법
화면이 너무 끊깁니다.
설치 과정을 따라가고 있는데, 화면이 너무 끊겨서 강의에서 어떤 버튼을 클릭하는지 또는 어떤 작업을 하는지 확인하기가 어렵습니다. 따라서 하기가 힘드네요. ㅜㅜ
-
해결됨[말 한마디로 뚝딱!] AI와 함께 나만의 수익화 웹사이트를 만드는 법
아파치 서버 실행후
test.php 저장해서 xampp 폴더에 넣고아파치 실행후 해당 경로로 localhost/test.php 접속해보니아래와 같이 뜨는데요. 접속이 안되는 이유가 혹시 그누보드 설치를 아직 못해서 그런가요?그누보드 설치에서 막혀서, php 작동 방식 및 다른 강의부터 보고 있었는데.. 이것도 안되네요. ㅜㅠ 만약 그누보드 설치와 관계가 없다면 왜 접속이 안되는걸까요? 주소창에 localhost/ 접속시그누보드 설치페이지는 잘 뜨거든요.ㅠㅠ 그리고 그누보드 설치 막혀서 문의를 남기긴했는데,이곳에서도 남겨보겠습니다. ㅠㅠ 해결좀 부탁드립니다. 강의 영상보고 계정생성 다 똑같이 해놨거든요. 그런데 어떤 오류가 있어서 진행이 안되는지 잘 모르겠네요. 흑
-
미해결처음 만난 리액트(React)
상태가 업데이트될때 컴포넌트 최상단의 console.log 코드가 두번 실행되는 이유가 궁금합니다.
import React, { useEffect, useState } from "react"; import useCounter from "./useCounter"; const MAX_CAPACITY = 10; export default function Accommodate() { const [isFull, setIsFull] = useState(false); const [count, increaseCount, decreaseCount] = useCounter(0); console.log(count,"rendor Accommodate", new Date().getMilliseconds()) useEffect(() => { console.log("===================="); console.log("useEffect() is called."); console.log("isFull:", isFull); }); useEffect(() => { setIsFull(count >= MAX_CAPACITY); console.log("Current count value:", count); }, [count]) return <> <button onClick={increaseCount}>입장</button> <button onClick={decreaseCount}>퇴장</button> {isFull && <p>정원이 가득 찼습니다.</p>} </>; }안녕하세요! 실습 진행 중에 이해가 안되는 부분이 있어 질문드립니다!우선 컴포넌트 내부에 포함된 state가 변경될때 컴포넌트가 재렌더링 되는게 맞을까요?그게 맞다면, 다음과 같은 순서로 실행된다고 생각했는데요.입장 버튼 클릭increaseCount가 실행되면서 count 상태가 변경됨Accommodate 컴포넌트가 재렌더링첫번째 useEffect함수가 실행두번째 useEffect함수가 실행 그리고 위 순서에 따라 console에는 다음과 같이 출력될 것이라고 예상했는데, 실제로는 캡쳐화면처럼 출력되더라구요.어떤 이유로 컴포넌트 최상단에 있는 console.log(count,"rendor Accommodate", new Date().getMilliseconds()) 코드가 두번 실행되는 건지 이해가 안됩니다.ㅠ제가 놓치고 있는 부분이 많은 것 같은데 어디서 부터 놓친건지 잘 정리가 되지 않네요!ㅠㅠ0 'rendor Accommodate' 991 ==================== useEffect() is called. isFull: false Current count value: 0 1 'rendor Accommodate' 430 ==================== useEffect() is called. isFull: false Current count value: 1
-
해결됨[말 한마디로 뚝딱!] AI와 함께 나만의 수익화 웹사이트를 만드는 법
IntelliJ IDEA, Git 설치 및 스프링부트 설정
본 강의는 끝까지 잘 따라왔다가 마지막에 실행해보니 error 가 생기며 끝나는데요.이후 강의가 끝나버려서 문의드리는데요. 어떤 문제일까요? 아, IntelliJ IDEA 사용중에 @EnableFeignClients 입력후 알트 +엔터 누르면import calss가 안생기던데 왜그럴까요?한국어 버전을 써서 그런건가요? 한참 헤메다가 어쩌다 노란색으로 처리가 되며 완성은 됐는데, 결과는 에러가 나서..
-
해결됨[말 한마디로 뚝딱!] AI와 함께 나만의 수익화 웹사이트를 만드는 법
그누보드 설치시 DB 연결 실패
강의에서 저만 안보이는지 모르겠지만 그누보드 설치 장면이 잘린 거 같습니다... XAMPP에서 ADMIN을 누르면 강제로 저기로 넘어가는데 강의에선 저 장면이 없거든요. 포트번호 수정에서 갑자기 넘어가는거 봐서 그 장면 삽입하시면서 영상이 잘린 게 아닐까 생각이 드네요... 그래서 스스로 설치하고 있는데 이 장면에서 HOST를 localhost:3307로 해도, 127.0.0.1로 해도, 127.0.0.1:3307로 해도 오류가 납니다. 지금 제 컴에서 mysql 실행이 mysql -uroot -p로는 안되고 강제로 TCP/IP 연결 명령어를 추가해야만 되는 상황인데 이 문제와도 연관이 있을까요
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
그랩마켓 웹화면 구현하기 -2 질문입니다.
header 에서는 header-area를 따로 만들어서 이미지를 관리를 하였는데body에서 배너는 배너-area를 따로 안만들고 바로 banner에 이미지를 넣어서 관리하는 이유가 따로 있나여?? 무슨차이인가요
-
미해결구글 애드센스 수익형 워드프레스 블로그 만들기
GP 테마 LOOP 템플릿 관련
GP 테마에서 메인 페이지 직접 제작하는 방법 강의를 수강중인데 현재 강의에서 나오는 QUERY LOOP나 POST TEMPLATE 이 제 테마에서는 나오질 않습니다. 이에 따라 강의에서 진행되는 내용을 이어갈수가 없는데 어떤 차이인지요? 아무리해도 POST TEMPLATE을 찾을수가 없습니다.[제 화면 캡쳐]
-
미해결HTML+CSS+JS 포트폴리오 실전 퍼블리싱(시즌2)
목소리 좀 키워주세요.
소리가 너무 작아서 잘 안들립니다..좋은 강의 감사하지만 들을 때마다 볼륨을 거의 최대로 해야 해서 불편한 부분이 있습니다. 소리좀 조금 키워주셨으면 좋겠습니다 ㅠ
-
해결됨[말 한마디로 뚝딱!] AI와 함께 나만의 수익화 웹사이트를 만드는 법
Gitlab 소스코드 접속이 안됩니다
안녕하세요 강의 1강에 있는 완성코드 접속 했는데 프론트 , 백 둘 다 아래처럼 404 page가 나옵니다확인 해주시면 감사하겠습니다
-
미해결[2025년 출제기준] 웹디자인기능사 실기시험 완벽 가이드
visibility:hidden; 적용 문제
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>index</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="container"> <header> <div class="header-logo"></div> <div class="nav"></div> </header> <div class="slide"> <div> <a href="#none"><img src="images/1200-1.jpg" alt="slide-1"></a> <a href="#none"><img src="images/1200-2.jpg" alt="slide-2"></a> <a href="#none"><img src="images/1200-3.jpg" alt="slide-3"></a> </div> </div> <div class="items"> <div class="news"></div> <div class="banner"></div> <div class="shortcut"></div> </div> <footer> <div class="footer-logo"></div> <div class="copyright"> <div></div> <div></div> </div> </footer> </div> <script src="script/jquery-1.12.4.js"></script> <script src="script/custom.js"></script> </body> </html> @charset "utf-8"; body { margin: 0; } .container { margin: auto; width: 1200px; border: 1px solid #000; } header { display: flex; justify-content: space-between; } header > div { height: 100px; border: 1px solid #000; } .header-logo { width: 200px; } .nav { width: 600px; } /* slide */ .slide { position: relative; width: 1200px; height: 300px; border: 1px solid #000; } .slide > div { font-size: 0; } .slide > div > a { position: absolute; top: 0; left: 0; animation: slide 10s linear infinite; opacity: 0; } .slide > div > a:nth-child(2) { animation-delay: 3.5s; } .slide > div > a:nth-child(3) { animation-delay: 7s; } @keyframes slide { 0% { opacity: 0; visibility: hidden; } 5% { opacity: 1; } 35% { opacity: 1; } 40% { opacity: 0; } 100% { opacity: 0; } } /* slide */ .items { display: flex; } .items > div { height: 200px; border: 1px solid #000; flex:1; } footer { display: flex; } footer > div { height: 100px; border: 1px solid #000; } .footer-logo { width: 200px; } .copyright { width: 1000px; } .copyright > div { box-sizing: border-box; border: 1px solid #000; height: 50%; }현재 섹션8-5번 강의 수강중입니다.강의에서 말씀하신대로 세번째 슬라이드 사진이 투명도 0 상태로 최상위 계층에 있는 상태여서 visibility: none; 속성을 주었는데, 속성을 넣어도 다른 슬라이드 사진을 눌러도 세번째 슬라이드사진이 클릭 되는데 어떤부분이 잘못되었을까요?
-
해결됨React, Node.js, MongoDB로 만드는 나만의 회사 웹사이트: 완벽 가이드
req.cookies.token == undefined 현상
logout을 해보니 400BadRequest:이미 로그아웃 됨 상태가 지속됩니다. console.log(req.cookies.token); 출력해보니 undefined 라고 출력됩니다. 쿠키를 제대로 읽지 못하는것 같은데 왜 이런 현상이 뜨는지 궁금합니다.. const express = require("express"); const router = express.Router(); const bcrypt = require("bcrypt"); const User = require("../models/User"); const axios = require("axios"); const jwt = require("jsonwebtoken"); router.post("/signup", async (req, res) => { try { const { username, password } = req.body; const existingUser = await User.findOne({ username }); if (existingUser) { return res.status(400).json({ message: "이미 존재하는 사용자입니다." }); } const hashedPassword = await bcrypt.hash(password, 10); const user = new User({ username, password: hashedPassword, }); await user.save(); res.status(201).json({ message: "회원가입이 완료되었습니다." }); } catch (error) { res.status(500).json({ message: "서버 오류가 발생했습니다." }); console.log(error); } }); router.post("/login", async (req, res) => { try { const { username, password } = req.body; const user = await User.findOne({ username }).select("+password"); //왜인지 password가 select되지 않아서 추가함 if (!user) { return res.status(401).json({ message: "존재하지 않는 사용자입니다." }); } if (!user.isActive) { return res.status(401).json({ message: "비활성화된 사용자입니다." }); } if (user.isLoggedIn == true) { return res.status(401).json({ message: "이미 접속 중인 사용자입니다." }); } const isValidPassword = await bcrypt.compare(password, user.password); //비밀번호 비교 if (!isValidPassword) { user.failedLoginAttempts += 1; user.lastLoginAttempt = new Date(); if (user.failedLoginAttempts >= 5) { user.isActive = false; //다섯번 틀리면 계정 비활성화 ㅋㅋ await user.save(); return res.status(401).json({ message: "비밀번호를 5회 이상 틀려 계정이 비활성화되었습니다.", }); } await user.save(); return res.status(401).json({ message: "비밀번호가 일치하지 않습니다.", remainingAttempts: 5 - user.failedLoginAttempts, }); } user.failedLoginAttempts = 0; user.lastLoginAttempt = new Date(); user.isLoggedIn = true; try { const response = await axios.get("https://api.ipify.org?format=json"); //공공장소 사용금지요 const ipAddress = response.data.ip; //한번 정제함 user.lastLoginIp = ipAddress; } catch (error) { console.log("IP 주소를 가져오는데 실패했습니다: ", error.message); } await user.save(); const token = jwt.sign( { userId: user._id, username: user.username }, process.env.JWT_SECRET, { expiresIn: "24h" } //토큰 만료는 24시간 ); console.log(token); //오 된다 res.cookie("token", token, { httpOnly: true, //자바스크립트에서 쿠키 접근 불가 secure: "production", //https에서만 쿠키 전송 sameSite: "strict", //같은 사이트에서만 쿠키 전송 maxAge: 24 * 60 * 60 * 1000, //24시간 }); const userWithoutPassword = user.toObject(); //구글링 해보니 이렇게 하면 문서 타입을 일반 객체로 변환할 수 있다고 한다 delete userWithoutPassword.password; //보안때문에 비밀번호는 삭제할 수 있다고 한다 res.json({ user: userWithoutPassword }); } catch (error) { console.log("서버 오류: ", error); res.status(500).json({ message: "서버 오류가 발생했습니다." }); } }); router.post("/logout", async (req, res) => { console.log(req.cookies.token); try { const token = req.cookies.token; if (!token) { return res.status(400).json({ message: "이미 로그아웃된 상태입니다." }); } try { const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findById(decoded.userId); if (user) { user.isLoggedIn = false; await user.save(); } } catch (error) { console.log("토큰 검증 오류: ", error.message); } res.clearCookie("token", { httpOnly: true, secure: "production", sameSite: "strict", }); res.json({ message: "로그아웃되었습니다." }); } catch (error) { console.log("로그아웃 오류: ", error.message); res.status(500).json({ message: "서버 오류가 발생했습니다." }); } }); router.delete("/delete/:userId", async (req, res) => { try { const user = await User.findByIdAndDelete(req.params.userId); if (!user) { return res.status(404).json({ message: "사용자를 찾을 수 없습니다." }); } res.json({ message: "사용자가 성공적으로 삭제되었습니다." }); } catch (error) { res.status(500).json({ message: "서버 오류가 발생했습니다." }); } }); module.exports = router;
-
해결됨[말 한마디로 뚝딱!] AI와 함께 나만의 수익화 웹사이트를 만드는 법
[해결] 그누보드 설치시 DB 연결 실패
강의에서는 gnuboard DB를 3307로 사용하는데 host에 그냥 localhost만 쓸 경우 자꾸 3306으로 연결 되서 연결 실패하더라구요 다른 config 설정을 바꿔주어야 하나 엄청 찾다가.. host 부분에 localhost가 아닌 localhost:3307로 써주니 3307 port의 mysql로 접속되어 db 설치가 됩니다.다른 해결 방법이 있는진 모르겠지만.. 이 방법도 있으니 막히시는 분들 참고 하세요