묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
next-auth 로그인 시 unauthorized 문제
문제가 몇일째 안풀리는게 있어 문의드려요제가 next-auth를 사용해서 로그인 프로세스를 해보고 있습니다.로컬에서 별도로 배포환경 만들어서 테스트를 했을 때에는 잘 되는데 배포시에 계속 Unauthorized 에러가 발생해서요제가 작성한 [...nextauth].ts 코드입니다.import NextAuth, { User } from 'next-auth'; import CredentialsProvider from 'next-auth/providers/credentials'; import { refreshAccessToken } from 'utils/tokenRefresh'; export default NextAuth({ providers: [ CredentialsProvider({ name: 'Credentials', credentials: { userId: { label: 'UserId', type: 'text', placeholder: 'jsmith' }, password: { label: 'Password', type: 'password' }, }, authorize: async (credentials) => { const res = await fetch(`${process.env.NEXT_PUBLIC_BACKEND_URL}/api/v1/users/signin`, { method: 'POST', body: JSON.stringify({ userId: credentials!.userId, password: credentials!.password, }), headers: { 'Content-Type': 'application/json' }, }); const user = await res.json(); // 로그인 성공 시 사용자 객체를 반환하고, 실패 시 null을 반환 if (res.ok && user) { console.log('ok user', user); return user; } else { console.log('error user', user); return false; } }, }), ], secret: process.env.NEXTAUTH_SECRET, // session: { // strategy: 'jwt', // maxAge: 0, // 브라우저가 닫히면 세션 종료 // // updateAge: 24 * 60 * 60, // 24시간마다 세션 갱신 (옵션) // }, callbacks: { async jwt({ token, user }) { // 사용자 로그인 시 토큰 설정 if (user) { return { ...token, accessJwt: user.result?.accessJwt, refreshJwt: user.result?.refreshJwt, companyId: user.result?.companyId, userName: user.result?.userName, accessTokenExpires: Date.now() + 3600 * 1000, }; } // 토큰 만료 확인 및 리프레시 if (Date.now() > token.accessTokenExpires!) { const newAccessJwt = await refreshAccessToken(token.refreshJwt!); return refreshAccessToken(newAccessJwt); } return token; }, async session({ session, token }) { if (token && token.accessJwt) { const customUser = session.user as User; if (!customUser.result) { customUser.result = { accessJwt: '', refreshJwt: '', companyId: '', userName: '', }; } customUser.result.accessJwt = token.accessJwt; customUser.result.refreshJwt = token.refreshJwt; customUser.result.companyId = token.companyId; customUser.result.userName = token.userName; session.user = customUser; } return session; }, }, }); NEXT_PUBLIC_BACKEND_URL 환경변수는 별도의 백엔드를 구성한 주소이구요 배포는 도커를 사용했습니다.FROM node:20.10 as builder # pnpm 설치 RUN npm install -g pnpm WORKDIR /usr/src/app COPY package*.json ./ RUN pnpm install ARG NEXT_PUBLIC_BACKEND_URL ARG NEXTAUTH_SECRET COPY . . RUN NEXT_PUBLIC_BACKEND_URL=https://${NEXT_PUBLIC_BACKEND_URL} NEXTAUTH_SECRET=${NEXTAUTH_SECRET} pnpm run build FROM node:20.10 RUN npm install -g pnpm WORKDIR /usr/src/app COPY --from=builder /usr/src/app/package*.json ./ RUN pnpm install --prod COPY --from=builder /usr/src/app . # COPY --from=builder /usr/src/app/.next ./.next EXPOSE 3000 CMD ["pnpm", "run", "dev"]NEXTAUTH_SECRET은 프론트 주소를 도커 실행 시 넣어줘야 한대서 도커 실행 할 때 환경변수로 따로 넣어줬구요Docs, Stackoverflow, ChatGPT 등 여러 방면으로 찾아봤는데 해결이 안되더라구요..강의하고는 별개 내용이긴 한데 더이상 물어볼 데가 없어서 강사님께 여쭈어봅니다..
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
Graphql 데이터 가지고 올때
이렇게 갈색으로 뜨는데, 에러가 되는 이유가 이 때문인 것 같아요. 무슨 이유 때문에 그럴까요? ㅠㅠㅠ
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
Github
터미널에 'git push origin master'를 입력하고 엔터를 누르면fatal: 'origin' does not appear to be a git repositoryfatal: Could not read from remote repository.Please make sure you have the correct access rightsand the repository exists. 이렇게 나와고 있어요. 어디서 실수했어요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
types.ts의 내용 중 누락된 게 많습니다
위는 선생님 파일 다운로드 한거의 package.json 이거는 제 포폴의 package.json 입니다ts-node 라든지 devDependencies에서도 빠진 게 몇개 있어보이는데.. 터미널에서 뭘 설치해야 할까요?? 수업 코드에서도 똑같이 설치한것같은데 types.ts 내용이 다르더라구요. ㅠㅠ이건 수업 코드 내의 package.json 입니다별 다를 건 없어 보입니다.. 근데 둘다 types.ts 내부 내용들이 누락된 게 너무 많더라구요 설치는 똑같이 한 거 같은데 버전 문제일까요?(types.ts)이런식으로 많이 다릅니다.. (오른쪽이 수업코드) +추가질문포트폴리오 파일인데 저런 오류가 뜹니다.. types.ts 에 누락된 내용이 많아서 그런걸까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
마지막 페이지가 1000번대라 한참넘어가야되네요
다른 공부하시는분들도 잘 적용됐는지 확인하는데 번거로움이있을거 같아서 말씀드려요!
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
Graphql과 RestAPI
제가 리액트, node.js의 RestAPI를 다루는 부분이 필요해서 수업을 듣게 되었습니다.(전체적인 리액트, node.js의 활용법도 필요함) 그런데 Graphql이란 것이 있어서 그 부분을 뛰어넘고 제가 필요한 부분만 들으려고 하니까 섹션 8과 9가 Graphql을 모르면 진행이 안되는 것 같더라고요. 이런 경우 실무에서도 이런 식으로 많이 쓰시는지, 점점 바뀌는 추세인 건지 궁금합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
안녕하세요 질문있습니다!
안녕하세요 질문 있습니다!refetchQueries 적을 때 자동완성되는 익스텐션이 뭔지 알 수 있을까용?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
9장 게시글 업로드하기 post 오류
[제로초 강좌 질문 필독 사항입니다]질문에는 여러분에게 도움이 되는 질문과 도움이 되지 않는 질문이 있습니다.도움이 되는 질문을 하는 방법을 알려드립니다.https://www.youtube.com/watch?v=PUKOWrOuC0c0. 숫자 0부터 시작한 이유는 1보다 더 중요한 것이기 때문입니다. 에러가 났을 때 해결을 하는 게 중요한 게 아닙니다. 왜 여러분은 해결을 못 하고 저는 해결을 하는지, 어디서 힌트를 얻은 것이고 어떻게 해결한 건지 그걸 알아가셔야 합니다. 그렇지 못한 질문은 무의미한 질문입니다.1. 에러 메시지를 올리기 전에 반드시 스스로 번역을 해야 합니다. 번역기 요즘 잘 되어 있습니다. 에러 메시지가 에러 해결 단서의 90%를 차지합니다. 한글로 번역만 해도 대부분 풀립니다. 그냥 에러메시지를 올리고(심지어 안 올리는 분도 있습니다. 저는 독심술사가 아닙니다) 해결해달라고 하시면 아무런 도움이 안 됩니다.2. 에러 메시지를 잘라서 올리지 않아야 합니다. 입문자일수록 에러메시지에서 어떤 부분이 가장 중요한 부분인지 모르실 겁니다. 그러니 통째로 올리셔야 합니다.3. 코드도 같이 올려주세요. 다만 코드 전체를 다 올리거나, 깃헙 주소만 띡 던지지는 마세요. 여러분이 "가장" 의심스럽다고 생각하는 코드를 올려주세요.4. 이 강좌를 바탕으로 여러분이 응용을 해보다가 막히는 부분, 여러 개의 선택지 중에서 조언이 필요한 부분, 제 경험이 궁금한 부분에 대한 질문은 대환영입니다. 다만 여러분의 회사 일은 질문하지 마세요.5. 강좌 하나 끝날 때마다 남의 질문들을 읽어보세요. 여러분이 곧 만나게 될 에러들입니다.6. 위에 적은 내용을 명심하지 않으시면 백날 강좌를 봐도(제 강좌가 아니더라도) 실력이 늘지 않고 그냥 코딩쇼 관람 및 한컴타자연습을 한 셈이 될 겁니다. 사진업로드를 하려할때 미리보기가 뜨지 않습니다. uploads에는 올린 사진들이 잘 뜹니다.게시글을 업로드하려 짹짹을 누르면 post 라우터가 없다고 뜹니다. POST /post 라우터가 없습니다.404Error: POST /post 라우터가 없습니다. at C:\Users\jyoun\udr_node\lecture\ch9\app.js:53:18 at Layer.handle [as handle_request] (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\layer.js:95:5) at trim_prefix (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:328:13) at C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:286:9 at Function.process_params (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:346:12) at next (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:280:10) at C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:646:15 at next (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:265:14) at C:\Users\jyoun\udr_node\lecture\ch9\routes\page.js:12:3 at Layer.handle [as handle_request] (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\layer.js:95:5) controllers/post.jsconst Post = require('../models/post'); const Hashtag = require('../models/hashtag'); exports.afterUploadImage = (req, res) => { console.log(req.file); res.json({ url: `/img/${req.file.filename}` }); }; exports.uploadPost = async (req, res, next) => { try { const post = await Post.create({ content: req.body.content, img: req.body.url, UserId: req.user.id, }); const hashtags = req.body.content.match(/#[^\s#]*/g); if (hashtags) { const result = await Promise.all(hashtags.map((tag) => { return Hashtag.findOrCreate({ where: { title: tag.slice(1).toLowerCase() } }); })); console.log('result', result); await post.addHashtags(result.map(r => r[0])); } res.redirect('/'); } catch (error) { console.error(error); next(error); } }; routes/post.jsconst express = require('express'); const multer = require('multer'); const path = require('path'); const fs = require('fs'); const { afterUploadImage, uploadPost } = require('../controllers/post'); const { isLoggedIn } = require('../middlewares'); const router = express.Router(); try { fs.readdirSync('uploads'); } catch (error) { console.error('uploads 폴더가 없어 uploads 폴더를 생성합니다.'); fs.mkdirSync('uploads'); } const upload = multer({ storage: multer.diskStorage({ destination(req, file, cb) { cb(null, '/uploads'); }, filename(req, file, cb) { const ext = path.extname(file.originalname); cb(null, path.basename(file.originalname, ext) + Date.now() + ext); }, }), limits: { fileSize: 5 * 1024 * 1024 }, }); // POST /post/img router.post('/img', isLoggedIn, upload.single('img'), afterUploadImage); // POST /post const upload2 = multer(); router.post('/', isLoggedIn, upload2.none(), uploadPost); module.exports = router; 개발자 도구로 보면 짹짹을 눌렀을때 갈곳이 없다는데 저는 깃헙 복사해서 똑같이 했는데 뭐가 문제인지 모르겠습니다. 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(); 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 || 8001); 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'), '번 포트에서 대기중'); }); main.html{% extends 'layout.html' %} {% block content %} <div class="timeline"> {% if user %} <div> <form id="twit-form" action="/post" method="post" enctype="multipart/form-data"> <div class="input-group"> <textarea id="twit" name="content" maxlength="140"></textarea> </div> <div class="img-preview"> <img id="img-preview" src="" style="display: none;" width="250" alt="미리보기"> <input id="img-url" type="hidden" name="url"> </div> <div> <label id="img-label" for="img">사진 업로드</label> <input id="img" type="file" accept="image/*"> <button id="twit-btn" type="submit" class="btn">짹짹</button> </div> </form> </div> {% endif %} <div class="twits"> <form id="hashtag-form" action="/hashtag"> <input type="text" name="hashtag" placeholder="태그 검색"> <button class="btn">검색</button> </form> {% for twit in twits %} <div class="twit"> <input type="hidden" value="{{twit.User.id}}" class="twit-user-id"> <input type="hidden" value="{{twit.id}}" class="twit-id"> <div class="twit-author">{{twit.User.nick}}</div> {% if not followingIdList.includes(twit.User.id) and twit.User.id !== user.id %} <button class="twit-follow">팔로우하기</button> {% endif %} <div class="twit-content">{{twit.content}}</div> {% if twit.img %} <div class="twit-img"><img src="{{twit.img}}" alt="섬네일"></div> {% endif %} </div> {% endfor %} </div> </div> {% endblock %} {% block script %} <script> if (document.getElementById('img')) { document.getElementById('img').addEventListener('change', function(e) { const formData = new FormData(); console.log(this, this.files); formData.append('img', this.files[0]); axios.post('/post/img', formData) .then((res) => { document.getElementById('img-url').value = res.data.url; document.getElementById('img-preview').src = res.data.url; document.getElementById('img-preview').style.display = 'inline'; }) .catch((err) => { console.error(err); }); }); } document.querySelectorAll('.twit-follow').forEach(function(tag) { tag.addEventListener('click', function() { const myId = document.querySelector('#my-id'); if (myId) { const userId = tag.parentNode.querySelector('.twit-user-id').value; if (userId !== myId.value) { if (confirm('팔로잉하시겠습니까?')) { axios.post(`/user/${userId}/follow`) .then(() => { location.reload(); }) .catch((err) => { console.error(err); }); } } } }); }); </script> {% endblock %}
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
Redux-Saga Login_REQUEST 문제입니다.
redux-saga 쪼개고 reducer 연결 하려고 하니 user reducer만 반응하고 LOG_IN_SUCCESS 는 반응을 하지 않습니다. 커뮤니티 게시판에서 여러가지를 확인해보고 해도 어디 부분이 잘못 된지 몰라 올려봅니다.. 제가 작성한 코드는 이러합니다. store/configureStore.js import { applyMiddleware, createStore, compose } from "redux"; import createSagaMiddleware from "redux-saga"; import { createWrapper } from "next-redux-wrapper"; import { composeWithDevTools } from "redux-devtools-extension"; import reducer from "../reducers"; import rootSaga from "../sagas"; const configureStore = (context) => { console.log("context", context); const sagaMiddleware = createSagaMiddleware(); const middlewares = [sagaMiddleware]; const enhancer = process.env.NODE_ENV === "production" ? compose(applyMiddleware(...middlewares)) // 배포용 : composeWithDevTools(applyMiddleware(...middlewares)); const store = createStore(reducer, enhancer); store.sagaTask = sagaMiddleware.run(rootSaga); return store; }; const wrapper = createWrapper(configureStore, { debug: process.env.NODE_ENV === "development", }); export default wrapper;reducers/index.js import { HYDRATE } from "next-redux-wrapper"; // HYDRATE = action import { combineReducers } from "redux"; import user from "./user"; import post from "./post"; const rootReducer = combineReducers({ index: (state = {}, action) => { switch (action.type) { case HYDRATE: console.log("HYDRATE", action); return { ...state, ...action.payload }; default: return state; } }, user, post, }); export default rootReducer; reducers/user.js export const initialState = { isLoggingIn: false, // 로그인 시도중 isLoggedIn: false, // 로그인 isLoggingOut: false, // 로그아웃 시도중 meUser: null, signUpData: {}, loginData: {}, }; export const LOG_IN_REQUEST = "LOG_IN_REQUEST"; export const LOG_IN_SUCCESS = "LOG_IN_SUCCESS"; export const LOG_IN_FAILURE = "LOG_IN_FAILURE"; export const LOG_OUT_REQUEST = "LOG_OUT_REQUEST"; export const LOG_OUT_SUCCESS = "LOG_OUT_SUCCESS"; export const LOG_OUT_FAILURE = "LOG_OUT_FAILURE"; export const loginRequestAction = (data) => ({ type: LOG_IN_REQUEST, value: data, }); export const logoutRequestAction = () => ({ type: LOG_OUT_REQUEST, }); const reducer = (state = initialState, action) => { // prettier-ignore switch(action.type) { case LOG_OUT_REQUEST : return {...state, isLoggingIn : true}; case LOG_IN_SUCCESS : return {...state, isLoggingIn : false, isLoggedIn:true, meUser:{...action.value, nickName:"Jay"}}; case LOG_IN_FAILURE : return {...state, isLoggingIn : false, isLoggedIn:false }; case "LOG_OUT_REQUEST" : return {...state, isLoggingOut:true}; case "LOG_OUT_SUCCESS" : return {...state, isLoggingOut:false, isLoggedIn:true, meUser:null}; case "LOG_OUT_FAILURE" : return {...state, isLoggingOut:false}; default: return state; } }; export default reducer;sagas/index.jsimport { all, fork, call } from "redux-saga/effects"; import userSaga from "./user"; export default function* rootSaga() { yield all([fork(userSaga)]); } sagas/user.js import { all, fork, put, delay, takeLatest } from "redux-saga/effects"; import { LOG_IN_FAILURE, LOG_IN_REQUEST, LOG_IN_SUCCESS, } from "../reducers/user"; function* logIn(action) { try { console.log("saga logIn"); // const result = yield call(logInAPI); yield delay(1000); yield put({ type: LOG_IN_SUCCESS, value: action.value, }); } catch (err) { console.error(err); yield put({ type: LOG_IN_FAILURE, error: err.response.data, }); } } function* watchLogIn() { yield takeLatest(LOG_IN_REQUEST, logIn); } function* watchLogOut() { yield takeLatest("LOG_OUT_REQUEST"); } export default function* userSaga() { yield all([fork(watchLogIn), fork(watchLogOut)]); }
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
evnet.target에 id 값이 없다 나오네요
event.target에 왜 id 가 없다 나오는지 알고 싶습니다
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
유데미 강의와 내용이 동일한가요??
유데미 강의와 동일한 버전인가요??
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
npx create-app reactexam1 에러
PS C:\reactexam1> npx create-react-app reactexam1npm ERR! code ENOENTnpm ERR! syscall lstatnpm ERR! path C:\Users\82108\AppData\Roaming\npmnpm ERR! errno -4058npm ERR! enoent ENOENT: no such file or directory, lstat 'C:\Users\82108\AppData\Roaming\npm'npm ERR! enoent This is related to npm not being able to find a file.npm ERR! enoentnpm ERR! A complete log of this run can be found in: C:\Users\82108\AppData\Local\npm-cache\_logs\2023-11-28T12_12_57_671Z-debug-0.log npx create-react-app reactexam1을 입력했을 때 계속 이런 에러가 뜹니다.폴더 위치를 c드라이브로 옮기는 것도 해보고 node.js를 다시 다운 받는 것도 해보았는데 계속해서 이런 에러가 발생합니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
23분 13초 관련 질문입니다.
리트윗 에러시, alert를 띄워주실 때, 게시글 . 수만큼 리렌더링이 발생하셔서 index.js 상위 페이지로 에러를 올려주셨는데, 설명하실떄 리트윗 에러에다가, 게시글 id까지 같이 넣어서, 그. 포스트 카드에만 에러메시지가 나오게 해서 해결하실 수있다고 하셨습니다. 어떤식으로 코드를 작성하면 되는지 해당 부분에 대한 코드 작성법도 알고싶습니다.어떤식으로 postId를 넘겨주고 useEffect를 활용할 수 있는지 알고 싶습니다.function retweetAPI(data) { return axios.post(`/post/${data}/retweet`); } function* retweet(action) { try { const result = yield call(retweetAPI, action.data); yield put({ type: RETWEET_SUCCESS, data: result.data, }); } catch (err) { console.error(err); yield put({ type: RETWEET_FAILURE, error: err.response.data, }); } }
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
섹션 13. 타입스크립트 설치 이슈
섹션 13의 본문 파트는 잘 따라 갔는데 혼자 freeboard에 진행하려 하니 계속 오류가 나네요..답변주신대로 설치 명령어의 오타를 수정해서 yarn add -D @graphql-codegen/typescript로 한 뒤 yarn generate를 실행하니 type.ts 이 안생기고 error Command failed with exit code 127. 라는 에러가 발생하네요ㅠㅠ 설치 파트에서 계속 막히니 힘드네요.. 확인 한번 해주실 수 있으실까요?
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
next 13,14버전으로 하고 있는데 antd에서 다음과같은 오류가 발생합니다.
SyntaxError: Cannot use import statement outside a module이란 에러가 발생하는데 왜그런걸까요 stackoverflow찾다보니 nextjs 바벨설정이 src 하위를 보게되있어서 es6문법을 변환못해준다고 next.config.js 파일에 아래 transpilePackages 설정을 저렇게 넣어주면 해당 오류가 사라지긴하는대 매번 이렇게 해야되는건지... 근본적인 해결하려면 어떻게 해야할까요const nextConfig = { reactStrictMode: true, transpilePackages: [ 'antd', '@ant-design', 'rc-util', 'kitchen-flow-editor', '@ant-design/pro-editor', 'zustand', 'leva', 'rc-pagination', 'rc-picker', 'rc-notification', 'rc-tooltip' ], }
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
styles.js 자동완성이 안되요
styles.js 자동완성이 안되는데 익스텐션 뭐 설치해야되나요?
-
미해결따라하며 배우는 TDD 개발 [2023.11 업데이트]
res.status(201) 부분에서 typeerror가 발생합니다
에러메시지: TypeError: Cannot read properties of undefined (reading 'status')res.status(200); 해당 코드에서 발생하는 에러인데 강사님이 코드돌리실때는 해당 에러가 발생하지 않는데 제 pc에서는 왜 에러가 발생하는지 잘 모르겠습니다...코드는 강의에서 입력하신 그대로 따라서 했습니다
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
2강 eslint
코드 똑같이 따라쳤는데도 04:42처럼 밑줄이 안뜹니다. 그리고 도표강의자료는 왜 안열리는건가요?
-
해결됨
예외처리가 더 효율적인 코드
유저 로그인 관련 메서드를 구현하던 중, 예외처리 방법 두가지 중 어느 것이 더 효율적(가독성, 유지보수 측면 등등..)인지 여쭤보고 싶습니다첫번째 방법: try문에 NotFoundException을 던지고, catch문에서 instanceof를 사용해서 예외의 타입을 확인하고 처리하기async userLogin(nickname: string, password: string) { try { const user = await this.usersRepository.findOne({ where: { nickname } }); // console.log(user) if (user && (await bcrypt.compare(password, user.password))) { return user; } else { throw new NotFoundException('아이디 또는 비밀번호가 일치하지 않습니다.'); } } catch (e) { console.error(e); if (e instanceof NotFoundException) { throw e; // NotFoundException은 그대로 던지기 } else { throw new InternalServerErrorException('알 수 없는 오류'); } } } 두번째 방법: try문에서는 일반적인 Error객체를 던진 후 catch문에서 error.message를 확인하여 예외 유형을 판단하기 async userLogin(nickname: string, password: string) { try { const user = await this.usersRepository.findOne({ where: { nickname } }); // console.log(user) if (user && (await bcrypt.compare(password, user.password))) { return user; } else { throw new Error('아이디 또는 비밀번호가 일치하지 않습니다.'); } } catch (error) { if (error.message === '아이디 또는 비밀번호가 일치하지 않습니다.') { throw new NotFoundException('아이디 또는 비밀번호가 일치하지 않습니다.'); } else { // 다른 예외 처리 throw new InternalServerErrorException('알 수 없는 오류'); } } }
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
AccessToken은 잘 만들어지는데 payload에 아무것도 안담겨요
로그인 시 받은 accesstoken을 밑에 /user/test의 헤더에 넣었습니다.처음에는 payload에 값이 담겼는데 갑자기 아무것도 안담기네요ㅜㅜ변경사항이 있었던 건 다 돌려봤는데도 도저히 뭐가 문제인지 모르겠어서 남깁니다.뭐가 문제인지도 모르겠어서 코드도 뭘 보여드려야 할 지 모르겠네요ㅜㅜ accesstoekn은 잘 만들어지는데.. 저 accesstoekn으로 UseGuards(AuthGuard('access')) 이 가드를 통과하는 거 아닌가요?validate()까지 간 거 보면 인가는 됐다고 생각했는데 왜 payload에 아무것도 안담기는지 모르겠네요ㅜㅜ