묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
Auth 모듈에서 JwtAuthGuard 가 아닌, JwtStrategy 를 provider 하는 이유?
import { Module, forwardRef } from '@nestjs/common'; import { AuthService } from './auth.service'; import { PassportModule } from '@nestjs/passport'; import { JwtModule } from '@nestjs/jwt'; import { CatsModule } from 'src/cats/cats.module'; import { JwtStrategy } from './jwt/jwt.strategy'; @Module({ imports: [ PassportModule.register({ defaultStrategy: 'jwt', session: false }), JwtModule.register({ secret: 'secret', signOptions: { expiresIn: '1y' }, }), forwardRef(() => CatsModule), ], providers: [AuthService, JwtStrategy], exports: [AuthService], }) export class AuthModule {} auth.module.ts 에서 JwtAuthGuard를 provider 에 추가하지 않고, JwtStrategy를 제공하는 이유가 궁금합니다. 실제로 Cat controller 에서는 authService의 JwtAuthGuard를 통해 호출되는거 아닌가요? JwtAuthGuard & JwtStrategy 둘다 provider 에 추가하라고 하면 그것대로 이해가 되는데, JwtStrategy만 추가하는게 이해가 잘 안되어서요ㅠㅠ
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
로그인 실패 ㅠㅠ
form에 email,password 입력 후 버튼을 누르면 다음과 같이 콘솔에 오류가 뜹니다.index.js app.post('/api/users/login',(req,res)=>{ User.findOne({email:req.body.email}) .then(user=>{ if(!user){ return res.json({ loginSuccess:false, message:"제공된 이메일에 해당하는 유저가 없습니다." }) } //만약 이 user에 해당 이메일을 갖고있는 user가 아예 없을경우 //요청한 이메일이 있다면 데이터 베이스에 있다면 비밀번호가 맞는 비밀번호 인지 확인. user.comparePassword(req.body.password,(err,isMatch)=>{ if(!isMatch) return res.json({loginSuccess:false, message:"비밀번호가 틀렸습니다"}) user.generateToken((err,user)=>{ if(err) return res.status(400).send(err); //token을 저장한다. 어디에? 쿠키에 보관. 로컬스토리지 res.cookie("x_auth",user.token) .status(200) .json({loginSuccess:true,userId:user._id}) }) }) //비밀번호 까지 맞다면 토큰 생성하기 }) .catch((err)=>{ return res.status(400).send(err); }) }) LoginPage.jsimport React,{useState} from 'react' //import axios from 'axios'; import {useDispatch} from 'react-redux'; import {loginUser } from '../../../_actions/user_action'; function LoginPage() { const dispatch = useDispatch(); const [email,setEmail]=useState(''); const [pwd,setPwd]=useState('') const onEmailHandler=(e)=>{ setEmail(e.target.value); } const onPwdHandler=(e)=>{ setPwd(e.target.value) } const onSubmitHandler=(e)=>{ e.preventDefault(); let body={ email:email, password:pwd } dispatch(loginUser(body)) } return ( <div style={{display:'flex', justifyContent:'center',alignItems:'center', width:'100%',height:'100vh' }}> <form style={{display:'flex',flexDirection:'column'}} onSubmit={onSubmitHandler}> <label>Email</label> <input type="email" value={email} onChange={onEmailHandler}/> <label>Password</label> <input type="password" value={pwd} onChange={onPwdHandler}/> <br/> <button>Login</button> </form> </div> ) } export default LoginPage;위 코드를 실행했더니 저렇게 오류내용이 나오면서 redux devtools로 보면 이렇게 axioserror 뜨네요,,어떻게 해결해야 할까요?
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
저장을 해도 실행이 안 돼요
🚨 아래의 가이드라인을 꼭 읽고 질문을 올려주시기 바랍니다 🚨질문 하시기 전에 꼭 확인해주세요- 질문 전 구글에 먼저 검색해보세요 (답변을 기다리는 시간을 아낄 수 있습니다)- 코드에 오타가 없는지 면밀히 체크해보세요 (Date와 Data를 많이 헷갈리십니다)- 이전에 올린 질문에 달린 답변들에 꼭 반응해주세요 (질문에 대한 답변만 받으시고 쌩 가시면 속상해요 😢)질문 하실때 꼭 확인하세요- 제목만 보고도 무슨 문제가 있는지 대충 알 수 있도록 자세한 제목을 정해주세요 (단순 단어 X)- 질문의 배경정보를 제공해주세요 (이 문제가 언제 어떻게 발생했고 어디까지 시도해보셨는지)- 문제를 재현하도록 코드샌드박스나 깃허브 링크로 전달해주세요 (프로젝트 코드에서 문제가 발생할 경우)- 답변이 달렸다면 꼭 확인하고 반응을 남겨주세요- 강의의 몇 분 몇 초 관련 질문인지 알려주세요!- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.codesendbox에서 ctrl+s 하면 저장하면서, console에 뜨는 구조가 아닌가요!?올려주신 해결책 다 사용해봤는데도 console창은 묵묵부답이네요...ㅠ
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
pagination 페이지 번호 유지하고 싶습니다.
예시로 pagination을 통해 4번째 게시물 목록을 보고 있는데여기서 새로 고침을 하거나4번 게시물 목록의 해당 게시글 클릭해서 들어가고 다시 뒤로 가기를 통해 게시물 목록으로 이동이 되었을 때4번 게시물 목록이 아닌 1번 게시물 목록으로 초기화가 되는데저는 4번 게시물 목록으로 유지하고 싶습니다. 다른 사이트의 게시물 홈페이지를 참고해 보면 page=4 이런 식으로 주소 창에 입력이 되어있는데 pages폴더에 폴더를 추가해서 유지를 해야 하나요?인프런에서 질문 & 답변 부분에서도 다음과 같이 사용되고 있습니다.https://www.inflearn.com/community/questions?page=2&order=recent 만약 폴더를 추가 해야 한다면 다음과 같이 폴더가 있을 때boards 하위 폴더에 추가하고 해당 page폴더 안에[boardId], new 폴더를 넣어야 할 까요?(page폴더 생성 안 한 상태입니다.)아니면 useState나 useRecoil을 사용해서 상태관리를 해야하는 건가요?어떻게 사용되는지 알고 싶습니다.
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
npm run dev 실행 시 emojis-list 관련 오류,,
위 파일이 client/index.js에 대한 코드입니다.루트 디렉토리에서 npm run dev를 실행시키면 밑 사진과 같은 오류가 뜹니다..node_modules, package.json 삭제 후 재설치도 해보고 client 디렉토리에서 npm install emojis-list도 해보고, npm uninstall emojis-list도 해보았지만 똑같은 오류가 떠서 페이지가 안열립니다..어떻게 해야 해결할 수 있을까요 ?
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
redux-thunk 관련 오류 !!
import React from 'react'; import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import {Provider} from 'react-redux'; //import 'antd/dist/antd.css' import { applyMiddleware,createStore } from 'redux'; import promiseMiddleware from 'redux-promise'; import thunk from 'redux-thunk'; import Reducer from './_reducers' const createStoreWithMiddleware = applyMiddleware(promiseMiddleware,thunk)(createStore) const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Provider store={createStoreWithMiddleware(Reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() )}> <App /> </Provider> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals(); 위 코드 실행했더니 export 'default' (imported as 'thunk') was not found in 'redux-thunk' (possible exports: thunk, withExtraArgument) 이란 오류가 떠서 node_modules, package.json 폴더도 삭제하고 다시 npm install을 했음에도 똑같은 오류가 떠요 ㅠ
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
husky
D:\coding\codecamp-frontend\class> npx husky install위 내용처럼 허스키를 설치하면 husky - .git can't be found (see https://typicode.github.io/husky/#/?id=custom-directory) 이렇게 .git을 찾을 수 없다고 뜹니다. 저는 작업물을 git으로 버전 관리했는데 찾아보니 package.json과 .git의 경로가 형제관계여야 오류가 안난다는 정보를 찾았습니다. 제 작업물의 폴더 구조가 최상위 폴더에 .git이 있고 저렇게 클래스 / 클래스_퀴즈 / 포폴 폴더에 package.json이 각각 있는 형태인데요.이러한 경우는 어떻게 해결해야 할까요?
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
npx create-react-app ./ 사용
npx create-react-app simplediray 를 통해 만들고 파일을 옮기는 것과 create-react-app ./을 사용하는게 동일한건가요 ?
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
서버 실행 시 에러 관련하여 답변받고 1차 조치했는데 여전하여서 질문 남깁니다
data-source hostname db로 변경하라는 말씀 듣고 변경해보았는데 여전히 해결이 안되어서 질문 남깁니다
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
엔티티 모두 작성 후 서버 실행 시 에러가 발생합니다
서버 실행 시 해당 에러가 발생해서 질문 남깁니다문제 파악에 도움될까해서 data-source.ts, server.ts 파일도 첨부합니다
-
해결됨클론코딩에서 알려주지 않는 것들 (보안, DDD, 마이크로서비스) 2편
다음 강의는 언제 나오나요?
학습 내용과는 관련없는 질문이지만...이제 12월이 거의 다 지나가는데 다음 강의는 언제쯤 나오나요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
Cannot read properties of null (reading 'useRef') 오류 질문
강의에서 진행 된 요소 추가 전까진 정상 작동 되는 것 확인 했습니다. Menu 추가 후 아래와 같은 오류가 출력 됩니다. Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:1. You might have mismatching versions of React and the renderer (such as React DOM)2. You might be breaking the Rules of Hooks3. You might have more than one copy of React in the same appSee https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem. TypeError: Cannot read properties of null (reading 'useRef') at useRef (C:\Users\sion\node_modules\react\cjs\react.development.js:1630:21) at Object.render (C:\Users\sion\node_modules\antd\lib\menu\index.js:19:37) at ReactDOMServerRenderer.render (C:\Users\sion\Documents\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:3535:44) at ReactDOMServerRenderer.read (C:\Users\sion\Documents\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:3373:29) at renderToString (C:\Users\sion\Documents\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:3988:27) at Object.renderPage (C:\Users\sion\Documents\prepare\front\node_modules\next\dist\next-server\server\render.js:50:851) at Document.getInitialProps (C:\Users\sion\Documents\prepare\front\.next\server\pages\_document.js:264:19) at loadGetInitialProps (C:\Users\sion\Documents\prepare\front\node_modules\next\dist\next-server\lib\utils.js:5:101) at renderToHTML (C:\Users\sion\Documents\prepare\front\node_modules\next\dist\next-server\server\render.js:50:1142) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) 터미널에 찍힌 로그입니다.react/react dom 버전은 동일함을 확인했고 16.14.0 버전 사용 중입니다. 구글링 중 react hook form을 인스톨 하라는 검색 결과가 있어 해당 패키지 설치 했습니다. 버전은 7.49.2 사용 중 입니다. 로컬에서 실행 된 화면입니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
상품수정 API 질문
상품 수정 api 질문합니다. 지금 보시면 update에는 async,await가 붙어있는데 데이터베이스를 거쳐 resolver로 가져오면 굳이 안붙어도 된다고 하셨는데 왜 붙어있는지 궁금합니다async update( {product,updateProductsService }:IProductsServiceUpdate):promise<Product> { const product=await this.findOne({productId}) this.checkSoldout({product}) }
-
미해결Do it! Node.js 프로그래밍 입문
thunder client 문제
thunder client 설치 후 당일은 문제 없이 사용했으나 다음 날 사용시 "Connection was forcibly closed by a peer." 메시지가 뜨면서 정상적으로 작동 하지 않음.12강 익스프레스 라우팅의 예제 파일로 실습 중이고 브라우저에서 'get'을 활용한 실습은 정상 작동함. thunder는 get, post,put 모두 작동 오류 발생.확장을 삭제 후 재설치하여도 동일 오류 발생VSC 버전: 1.84.2윈도우 버전: 10.0.19044.1288Thunder Client: 2.26.3
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
createUploadLink사용 할 때 오류가 발생합니다.
import에 문제가 발생했다고 하는 것 같은데 아무리 찾아봐도 해결이 안됩니다.ㅠ 어찌해야할까요
-
미해결습관부터 바꿔주는 Node.js & Express 기초
pm2 start ecosystem.config.js로 실행했는데 require로 작성하는 것에 에러가 뜹니다.
// server-register.cjs require("@babel/register"); require("./index.js"); // ecosystem.config.cjs module.exports = { apps: [ { name: "api", script: "./src/server-register.js", exec_mode: "cluster", watch: false, instances: 0, }, ], }; cli에서 pm2 start ecosystem.config.js로 실행했는데 처음엔 status가 online으로 잘 뜨지만 서버가 실행이 안됩니다. Cannot find module src/server-register.js' imported from /usr/local/lib/node_modules/pm2/lib/ProcessContainer.js 라고 나오는데 install도 다했는데 뭐가 문제일까요?
-
해결됨따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
강의 업데이트 질문드립니다
안녕하세요.채팅앱은 구름에듀에서 수강중입니다.구름에듀에도 강의 업데이트 가능하시면 부탁드립니다.좋은 강의 항상 감사합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
조회 시, select로 일부 필드만 가져올 때 GraphQL 처리
안녕하세요 :)아래 코드와 같이 상품 조회할 때 select를 통해 일부 필드만 가져오도록 해봤습니다.service의 findAll 메서드에서는 유틸리티 타입으로 반환하도록 하였고,resolver에서는 Query 데코레이터에 GraphQL에서 제공하는 PickType으로 반환하게 했는데, 에러가 발생합니다.. (적절한 값이 아니라는 에러 내용)이런 상황에서는 메서드 반환 타입과 GraphQL 타입 처리를 어떻게 해주는 것이 좋은지 감이 잘 안 잡혀서 질문드려요! // products.resolver.ts @Query(() => [PickType(Product, ['id', 'name', 'description'])]) fetchProducts(): Promise<Pick<Product, 'id' | 'name' | 'description'>[]> { return this.productsService.findAll(); }// products.service.ts findAll(): Promise<Pick<Product, 'id' | 'name' | 'description'>[]> { return this.productsRepository.find({ select: ['id', 'name', 'description'], }); }
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
redux-thunk import error
Attempted import error: 'redux-thunk' does not contain a default export (imported as 'thunk').ERROR in ./src/index.js 16:69-74export 'default' (imported as 'thunk') was not found in 'redux-thunk' (possible exports: thunk, withExtraArgument) 이런 오류가 뜨는데 어떻게 해결해야하는걸까요?? import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import { Provider } from 'react-redux'; import DatePicker from 'antd'; import { applyMiddleware, createStore } from 'redux'; import promiseMiddleware from 'redux-promise'; import thunk from 'redux-thunk' import Reducer from './_reducers'; const createStoreWithMiddleware = applyMiddleware(promiseMiddleware, thunk)(createStore) const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Provider store={createStoreWithMiddleware(Reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() )}> <App /> </Provider> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();
-
해결됨[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
passport.authenticate is not a function 도와주세요..
passport.authenticate is not a functionTypeError: passport.authenticate is not a function at exports.login (/home/node/app/controllers/auth.js:26:14) at Layer.handle [as handle_request] (/home/node/app/node_modules/express/lib/router/layer.js:95:5) at next (/home/node/app/node_modules/express/lib/router/route.js:144:13) at exports.isNotLoggedIn (/home/node/app/middlewares/index.js:15:9) at Layer.handle [as handle_request] (/home/node/app/node_modules/express/lib/router/layer.js:95:5) at next (/home/node/app/node_modules/express/lib/router/route.js:144:13) at Route.dispatch (/home/node/app/node_modules/express/lib/router/route.js:114:3) at Layer.handle [as handle_request] (/home/node/app/node_modules/express/lib/router/layer.js:95:5) at /home/node/app/node_modules/express/lib/router/index.js:284:15 at Function.process_params (/home/node/app/node_modules/express/lib/router/index.js:346:12) POST /auth/login 500 34.609 ms - 2536GET /main.css 304 2.895 ms - -현재 로그인을 눌렀을 때 이 오류가 생깁니다.해결방법을 모르겠습니다..localStrategy.jsconst passport = require('passport'); const {Strategy: localStrategy} = require('passport-local'); const User = require('../models/user'); const bcrypt = require('bcrypt'); module.exports = () => { passport.use(new localStrategy({ usernameField: 'email', passwordField: 'password', passReqToCallback: 'false' }, async (email, password, done) => { try { const exUser = await User.findOne({ where: {email}}); if (exUser) { const result = await bcrypt.compare(passport, exUser.passport); if(result) { done(null, exUser); } else { done(null, false, {message: '비밀번호가 일치하지 않습니다.'}); } } else { done(null, false, {message: '가입되지 않은 회원입니다.'}); } } catch(error) { console.error(error); done(error); } })); }; controllers/auth.jsconst User = require("../models/user"); const bcrypt = require('bcrypt'); const passport = require("../passport"); exports.join = async (req, res, next) => { const {nick, email, password} = req.body; try { const exUser = await User.findOne({ where: {email}}); if (exUser) { return res.redirect('/join?error=exist'); } const hash = await bcrypt.hash(password, 12); await User.create({ email, nick, password: hash, }); return res.redirect('/'); } catch (error) { console.error(error); next(error); } } //POST /auth/login exports.login = (req, res, next) => { passport.authenticate('local', (authError, user, info) => { if (authError) { console.error(authError); return next(authError); } if (!user) { return res.redirect(`/?loginError=${info.message}`); } return req.login(user, (loginError) => { if (loginError) { console.error(loginError); return next(loginError); } return res.redirect('/'); }); })(req, res, next); }; exports.logout = (req, res, next) => { req.logout(() => { res.redirect('/'); }) } app.jsconst express = require('express'); const cookieParser = require('cookie-parser'); const morgan = require('morgan'); const path = require('path'); const session = require('express-session'); const nunjucks = require('nunjucks'); const dotenv = require('dotenv'); const passport = require('passport'); dotenv.config(); // process.env const pageRouter = require('./routes/page'); const authRouter = require('./routes/auth'); const { sequelize } = require('./models'); const passportConfig = require('./passport'); const app = express(); passportConfig(); app.set('port', process.env.PORT || 8080); app.set('view engine', 'html'); nunjucks.configure('views', { express: app, watch: true, }); sequelize.sync({ force: false }) .then(() => { console.log('데이터베이스 연결 성공'); }) .catch((err) => { console.error(err); }); app.use(morgan('dev')); app.use(express.static(path.join(__dirname, 'public'))); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser(process.env.COOKIE_SECRET)); app.use(session({ resave: false, saveUninitialized: false, secret: process.env.COOKIE_SECRET, cookie: { httpOnly: true, secure: false, }, })); app.use(passport.initialize()); app.use(passport.session()); app.use('/', pageRouter); app.use('/auth', authRouter); app.use((req, res, next) => { const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`); error.status = 404; next(error); }); app.use((err, req, res, next) => { res.locals.message = err.message; res.locals.error = process.env.NODE_ENV !== 'production' ? err : {}; res.status(err.status || 500); res.render('error'); }); app.listen(app.get('port'), () => { console.log(app.get('port'), '번 포트에서 대기중'); });