월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨[리뉴얼] React로 NodeBird SNS 만들기
새로 올리신 리액트쿼리 버전에서 getServerSideProps대신 getStaticProps 쓰는 이유가 궁금합니다.
안녕하세요. 자꾸 귀찮게 해드려서 죄송합니다. 리액트쿼리로 바꾸신거 조금씩 따라하면서 변형하고 있는데 /user/[id] /post/[id] 에서 getServerSideProps대신 getStaticProps 로 바뀐걸 봤습니다. 정적은 빌드시에 데이터 불러오는거라서 데이터 변경가능성이 있는 post/[id]같은 경우는 정적을 쓰면 안될것같은 느낌인데 무슨 장점이나 혹시 바꾸신 이유가 있을까요? 그리고 queryClient.prefetchQuery에 대해서도 궁금한점이 있습니다. 현재 상품을 등록하는 /item/register.tsx를 작성중이고 로그인된 유저에서 정보를 가져와야 해서 서버사이드 랜더링을 적용중에 있습니다. 유저정보를 가져오는 api export function loadMyInfoAPI() { return axios.get('/user').then((response) => response.data); } back에서 라우터 부분 // 로그인 유저 정보 얻기 router.get('/', async (req, res, next) => { // GET /user 로그인 유지 위해 로그인한 유저의 정보 전송 console.log('req.user?', req.user); try { if (req.user) { // 로그인 됐을경우 const userDataWithoutPassword = await User.findOne({ // 프론트로 보낼 유저 정보를 재가공 where: { id: req.user.id }, attributes: { exclude: ['password'], // 비밀번호 제외 }, include: [ { model: User, as: "Customers", attributes: ["id", "company"], exclude: ['UsersRelation'], } ] }) res.status(200).json(userDataWithoutPassword); console.log(JSON.stringify(userDataWithoutPassword)); } else { res.status(200).json(null); } } catch (error) { console.error(error); next(error); } }); 프론트 /item/register.tsx에서 기본 골자는 const Register = () => { ... const { data: myUserInfo } = useQuery<User>('user', loadMyInfoAPI); ... 중략 return ( <AppLayout> <div>{JSON.stringify(myUserInfo)}</div><br /> ... 중략 <div> <List className="demo-loadmore-list" itemLayout="horizontal" dataSource={myUserInfo.Customers} renderItem={(item) => ( <List.Item key={item.id} actions={[ <> <Button type="primary" shape="circle">등록</Button> </> ]} > <List.Item.Meta title={ <> {item.company}<span> | </span><span>담당자: {item.id}</span> </>} /> </List.Item> )} /> </div> 이렇게 로그인된 유저 정보를 출력해주는 부분이 있습니다. myUserInfo.Customers는 me.followers와 흡사한 개념으로 맍들었고요. 서버사이드 랜더링은 export const getServerSideProps = async (context: GetServerSidePropsContext) => { const cookie = context.req ? context.req.headers.cookie : ''; axios.defaults.headers.Cookie = ''; if (context.req && cookie) { axios.defaults.headers.Cookie = cookie; } const response = await loadMyInfoAPI(); if (!response) { return { redirect: { destination: '/', permanent: false, }, }; } return { props: {}, }; }; 단순히 로그인체크만 해서 로그인이 안됐을경우 리다이랙트만 해주는 서버사이드랜더링을 하면 back에서 console.log('req.user?', req.user); 값은 정상적으로 user객체를 출력합니다. 프론트 페이지도 정상적으로 데이터가 나오고요. JSON.stringify(myUserInfo)로 출력한 데이터는 object {9} id : tester1 company : testers name : test phone : 101010 email : 2 role : NOVICE createdAt : 2021-12-17T04:43:25.000Z updatedAt : 2021-12-17T04:43:25.000Z Customers [2] 0 {2} id : ttt3 UsersRelation {4} 1 {2} id : tttt UsersRelation {4} createdAt : 2021-12-17T08:05:07.000Z updatedAt : 2021-12-17T08:05:07.000Z customerId : tttt providerId : tester1 이렇게 나옵니다. 물론 데이터를 받아와서 주입해주는 부분이 없기때문에 /item/register로 주소를 쳐서 들어가면 오류가 납니다. 데이터를 주입시켜주기 위해 쿼리클라이언트를 사용할 경우 export const getStaticProps = async () => { const queryClient = new QueryClient(); await queryClient.prefetchQuery(['user'], () => loadMyInfoAPI()); return { props: { dehydratedState: JSON.parse(JSON.stringify(dehydrate(queryClient))), }, }; }; back에서 user는 undefined로 나오게 되고 오류가 발생합니다.. 어떠한 부분때문에 같은loadMyInfoAPI 를 쓰는데도 불구하고 다른 결과가 나오는지 궁금함니다. 프론트 터미널의 오류메시지 TypeError: Cannot read property 'Customers' of undefined at Register (D:\3programming\excuse_moa\front_rq\.next\server\pages\item\register.js:2657:36) at processChild (D:\3programming\excuse_moa\front_rq\node_modules\react-dom\cjs\react-dom-server.node.development.js:3353:14) at resolve (D:\3programming\excuse_moa\front_rq\node_modules\react-dom\cjs\react-dom-server.node.development.js:3270:5) at ReactDOMServerRenderer.render (D:\3programming\excuse_moa\front_rq\node_modules\react-dom\cjs\react-dom-server.node.development.js:3753:22) at ReactDOMServerRenderer.read (D:\3programming\excuse_moa\front_rq\node_modules\react-dom\cjs\react-dom-server.node.development.js:3690:29) at Object.renderToString (D:\3programming\excuse_moa\front_rq\node_modules\react-dom\cjs\react-dom-server.node.development.js:4298:27) at renderPage (D:\3programming\excuse_moa\front_rq\node_modules\next\dist\server\render.js:596:45) at Object.ctx.renderPage (D:\3programming\excuse_moa\front_rq\.next\server\pages\_document.js:1161:30) at Function.getInitialProps (D:\3programming\excuse_moa\front_rq\.next\server\pages\_document.js:621:19) at Function.getInitialProps (D:\3programming\excuse_moa\front_rq\.next\server\pages\_document.js:1169:87) error - Error: "MyDocument.getInitialProps()" should resolve to an object. But found "undefined" instead. at Object.loadGetInitialProps (D:\3programming\excuse_moa\front_rq\node_modules\next\dist\shared\lib\utils.js:75:15) at runMicrotasks (<anonymous>) at processTicksAndRejections (internal/process/task_queues.js:93:5) at async renderDocument (D:\3programming\excuse_moa\front_rq\node_modules\next\dist\server\render.js:609:30) at async Object.renderToHTML (D:\3programming\excuse_moa\front_rq\node_modules\next\dist\server\render.js:647:28) at async doRender (D:\3programming\excuse_moa\front_rq\node_modules\next\dist\server\next-server.js:1149:38) at async D:\3programming\excuse_moa\front_rq\node_modules\next\dist\server\next-server.js:1241:28 at async D:\3programming\excuse_moa\front_rq\node_modules\next\dist\server\response-cache.js:64:36 { page: '/item/register' } back의 터미널 로그 req.user? undefined GET /user 200 1.716 ms - 4
- 해결됨[리뉴얼] React로 NodeBird SNS 만들기
시퀄라이즈 다대다관계 질문이 있습니다.
안녕하세요. 강의 듣고 조금씩 변형해가면서 연습하고 있습니다. User와 Follow 모델을 참고해서 User와 UserRealation (판매자-구매자 관계)를 작성했습니다. const User = sequelize.define('User', { // MySQL에는 users 테이블 생성 id: { // 사업자번호 type: DataTypes.STRING(30), allowNull: false, // 필수 unique: true, // 유일한 값 primaryKey: true, }, ... 중략 User.associate = (db) => { db.User.belongsToMany(db.User, { through: 'UsersRelation', as: 'Providers', foreignKey: 'customerId' }); // 판매자-구매자 관계 db.User.belongsToMany(db.User, { through: 'UsersRelation', as: 'Customers', foreignKey: 'providerId' }); // 판매자-구매자 관계 판매자가 구매자를 등록하는 (팔로워 등록과 유사)간단한 API는 이렇고요, export function addCustomerAPI(data: { providerId: string, customerId: string } ) { return axios.patch('/user/addcustomer', data).then((response) => response.data); } 이걸 실행하면 라우트에서 try { const customer = await User.findOne({ // 아이디 찾기 where: { id: req.body.customerId, } }); const provider = await User.findOne({ // 아이디 찾기 where: { id: req.body.providerId, } }); if (!customer || !provider) { return res.status(403).send('해당 아이디가 존재하지 않습니다.'); } // await provider.addCustomers(req.body.customerId); await customer.addCustomers(req.body.providerId); res.status(200).json({ customerId: req.body.customerId }); // res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3060'); } 이렇게 처리하는 방식입니다. tester1이라는 판매자 아이디로 로그인해서 tttt라는 구매자를 등록하는 과정인데 제 생각으로는 await provider.addCustomers(req.body.customerId); 이렇게 해야 providerId : tester1, customerId: tttt 이렇게 들어갈것 같은데 실제로 sql에서 까보면 반대로 들어가있습니다. 그래서 await customer.addCustomers(req.body.providerId); 이렇게 해야 제가 의도한대로 들어가는데.. customer에 addcustomer로 providerId를 넣는다는게 좀 이해가 안되서 헷갈리네요. (req.body를 까보면 providerId: tester1, customerId: tttt로 잘 받아왔습니다.) 처음에는 db.User.belongsToMany(db.User, { through: 'UsersRelation', as: 'Providers', foreignKey: 'providerId' }); // 판매자-구매자 관계 db.User.belongsToMany(db.User, { through: 'UsersRelation', as: 'Customers', foreignKey: 'customerId' }); // 판매자-구매자 관계 이렇게 했다가 강의에있는 User모델 보고 db.User.belongsToMany(db.User, { through: 'UsersRelation', as: 'Providers', foreignKey: 'customerId' }); // 판매자-구매자 관계 db.User.belongsToMany(db.User, { through: 'UsersRelation', as: 'Customers', foreignKey: 'providerId' }); // 판매자-구매자 관계 이렇게 바꿔놓은건데도 동일하게 작동합니다. SQL도 잘 못하긴 하지만 그냥 SQL INSERT문으로 생각하면 간단한데 시퀄라이즈 모델 개념이 부족해서 너무 헷갈리네요..
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
간단한질문입니다! 수동설치하는 이유를 알수있을까요?
현영님! 2가지 질문 좀 드리겠습니다 :) 1 . npx create-next-app 안하시고 수동설치 하시는 이유는 무엇인가요? 2.왜 저는 수동설치가 안될까요 ㅠ 윈도우 환경에서는 되는데 맥환경에서는 pakage.json 의 "dev" : "next" dev를 자꾸 찾을수 없다고 나와요..
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
이미지 업로드 질문있습니다 (이미지 확장 가능 thumb 생성 X)
강의 따라서 진행하고 aws s3에 aws-upload.zip 파일을 becket name에 복사한 뒤에 Amazon S3 링크 URL도 저장했습니다. 그런데 이미지 업로드 시 위와 같이 여전히 나옵니다. lambda/index.js 소스코드도 문제가 없습니다. const AWS = require('aws-sdk'); const sharp = require('sharp'); const s3 = new AWS.S3(); exports.handler = (event, context, callback) => { const Bucket = event.Records[0].s3.bucket.name; // react-nodebird-s3 const Key = decodeURIComponent(event.Records[0].s3.object.key); // original/12312312_abc.png, decodeURIComponent: 한글 깨짐현상 해결 console.log('Bucket: ', Bucket, 'Key: ', Key); const filename = Key.split('/')[Key.split('/').length - 1]; // 파일이름 추출 const ext = Key.split('.')[Key.split('.').length - 1].toLowerCase(); // 확장자 추출.toLowerCase(), 확장자 대문자를 소문자로 const requiredFormat = ext === 'jpg' ? 'jpeg' : ext; console.log('filename', filename, 'ext', ext); try { const s3Object = await s3.getObject({ Bucket, Key }).promise(); console.log('original', s3Object.Body.length); const resizedImage = await sharp(s3Object.Body) .resize(400, 400, { fit: 'inside' }) .toFormat(requiredFormat) .toBuffer(); await s3 .putObject({ Bucket, Key: `thumb/${filename}`, Body: resizedImage, }) .promise(); console.log('put', resizedImage.length); return callback(null, `thumb/${filename}`); } catch (error) { console.error(error); return callback(error); } }; // ImagesZoom/index.js <img src={`${v.src.replace(/\/thumb\//, '/original/')}`} alt={v.src} /> // routes/post.js router.post('/images', isLoggedIn, upload.array('image'), (req, res, next) => { console.log(req.files); // 업로드가 어떻게 됬는지 정보들이 담겨있음 res.json(req.files.map((v) => v.location.replace(/\/original\//, '/thumb/'))); // original에서 thumb 이미지를 가져옴 // location 자체에 주소가 담겨있음, PostFrom에 image src에 그대로 전달(backURL 필요 X) }); 그리고 S3 bucket에 thumb 파일이 생성이 되지 않았습니다. lambda 함수에서 모니터링을 해보니 실패라고 떠 있습니다. 무엇이 문제인지 파악이 되지 않아 질문을 올립니다.
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
key: 'image'와 router.post('/image) 관련 질문있습니다.
key: 'image'와 routes/post.js에서 router.post('./images', upload.array('image'))가 일치해야 그대로 받을 수가 있다고 하셨는데 PostForm.js에서 onChangeImages 함수에 매개변수로 e를 받아서 e.target.files를 console 찍어보면 FileList가 나옵니다. 여기서 일치한다는게 뭔지 이해가 안되는데... key: image는 어디에 있고 images는 단수에서 복수가 되는건가요? 조금 이해가 안되서 그러는데 간략하게 설명해주실수 있나요? // components/PostForm.js const onClickImageUpload = useCallback(() => { imageInput.current.click(); }, [imageInput.current]); const onChangeImages = useCallback((e) => { console.log('images', e.target.files); // 배열X, 유사배열 const imageFormData = new FormData(); // 멀티파트 형식으로 서버에 보낼수 있다 [].forEach.call(e.target.files, (f) => { imageFormData.append('image', f); // key: 'image', value(값): f }); dispatch({ type: UPLOAD_IMAGES_REQUEST, data: imageFormData, }); }, []); // routes/post.js router.post('/images', isLoggedIn, upload.array('image'), (req, res, next) => { console.log(req.files); // 업로드가 어떻게 됬는지 정보들이 담겨있음 res.json(req.files.map((v) => v.location)); // location 자체에 주소가 담겨있음, PostFrom에 image src에 그대로 전달(backURL 필요 X) }); // POST /post/images, // upload.array(), upload.single(), upload.none()
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
typescript 관련 질문입니다..ㅠㅠ
[제로초 강좌 질문 필독 사항입니다]질문에는 여러분에게 도움이 되는 질문과 도움이 되지 않는 질문이 있습니다.도움이 되는 질문을 하는 방법을 알려드립니다. 안녕하세요 제로초님~!!강의수가 정말 많아서 제대로 흡수하려고 천천히 이해하며 듣다보니 몇달이..지낫네요 ㅎㅎ 제로초님 수업 js를 ts로 변환하면서 수업을 듣고 있습니다. 그러던중.. getServerSideProps 에서 아래와 같이 타입에러가 나고있는데 ㅠㅠ vscode에서 추천하는 타입도 해보고 다른 내용도 검색해보면서 해봤는데 저 오류 해결이 잘 안되네요 혹시 어떤 오류인지 ㅠㅠ 알고계신가 해서 질문 남깁니당..// pages/index.tsx // store/configureStore.tsx
- 해결됨[리뉴얼] React로 NodeBird SNS 만들기
리덕스 미들웨어로 비동기 관리 질문
안녕하세요 제로초님 전역상태 관련해서 궁금한점이 생겨 질문드립니다.1. 예를들어 게시글 생성페이지와 게시글수정페이지가 {title: '' content: ''} 와같이 같은 폼양식이면 같은 전역상태를 사용하는 것인가요? 그렇다면 제로초라는 게시물 수정페이지에 들어가면 게시글아이디를 통해 비동기로 서버로부터 게시물 데이터를 받고 전역상태에 값을 셋팅해준다음 화면에 뿌려주고페이지를 벗어난다면 게시글이라는 전역상태를 모두 빈값으로 초기화를 하여 게시글 생성페이지에 진입시 모두 빈값으로 화면에 뿌려주는 방식인건가요?? 헷갈립니다..2. 다른 질문이긴하지만 컴포넌트 파일에서 컴포넌트 바깥에 데이터를 두게된다면(ex: 상태의 초기값이나 상수) 성능에 안좋은건가요??
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
await user.addFollowers(req.user.id)에서 궁금한점이 있습니다.
user.addFollowers(req.user.id)를 했을경우 데이터 베이스를 보니깐 followedId에는req.user.id가 , followingId에는 userId가 들어가 있는걸 확인했는데요. 저희가 데이터베이스 구조를 짤때 as를 Followers 해주고 foreignkey를 FollowingId로 해줬잖아요? 그러면 user.addFollowers(req.user.id)를 했을경우 as: Followers 의 foreignkey가 FollowingId니깐 req.user.id가 FollowingId에 들어가는게 맞는거 아닌가요?? 왜 반대로 됬는지 이해가 안됩니다 ㅠㅠ
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
CredentialsError: Missing credentials in config 질문 있습니다
sudo su 관리자 모드에서 vim .env 통해 S3_ACCESS_KEY_ID와 S3_SECRET_ACCESS_KEY를 추가하고 wq를 통해 저장까지 했습니다. 그런데 CredentialsError: Missing credentials in config 에러가 생깁니다. 그래서 제가 확인해본 것이 pakage.json과 .env를 다시 봤는데 문제가 없습니다.. 뭐가 문제인지 조언 부탁드립니다.. 질문이 많아서 죄송합니다..(계속해서 헤매는데 못 찾겠습니다..)
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
게시글 업로드 문제(401) But.. 로그인 되었음(cookie 보유 확인)
알려주신대로 npm start 통해 로그인 문제는 해결이 되었습니다. 로그인은 되어 있습니다 그런데 게시글 업로드 시 401 에러(로그인이 필요하다)가 생깁니다. <확인결과> network - post - Cookie 탭에 connenct.sid(Cookie) 보유 확인 Aplication/Cookies에 connect.sid 확인 ---------------------------------------------- 무엇이 문제인지 파악이 되지 않습니다 . 혹시나 문제는 없었지만 getServerSideProps 문제인건가요? /front/pages/index.js export const getServerSideProps = wrapper.getServerSideProps((store) => async ({ req }) => { const cookie = req ? req.headers.cookie : ''; // req가 있다면 cookie에 요청에 담겨진 cookie를 할당한다. axios.defaults.headers.Cookie = ''; // 요청이 들어올 때마다 초기화 시켜주는 것이다. 여기는 클라이언트 서버에서 실행되므로 이전 요청이 남아있을 수 있기 때문이다 if (req && cookie) { axios.defaults.headers.Cookie = cookie; // 서버일때랑 cookie를 써서 요청을 보낼 때만 headers에 cookie를 넣어준다 } store.dispatch({ type: LOAD_MY_INFO_REQUEST, // user }); store.dispatch({ type: LOAD_POSTS_REQUEST, // post }); store.dispatch(END); await store.sagaTask.toPromise(); // store/configureStore.js > store.sagaTask }); // 이 부분이 Home 보다 먼저 실행됨
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
getServerSideProps 문제 질문있습니다.
cookie가 있는걸로 봐서는 프론트에서 인식을 못하고 있는것 같다고 하셔서 살펴보는데 찾지를 못하겠습니다.. 일단 pages/index,js의 getServerSideProps 는 문제가 없어 보입니다. ```javascript export const getServerSideProps = wrapper.getServerSideProps((store) => async ({ req }) => { const cookie = req ? req.headers.cookie : ''; // req가 있다면 cookie에 요청에 담겨진 cookie를 할당한다. axios.defaults.headers.Cookie = ''; // 요청이 들어올 때마다 초기화 시켜주는 것이다. 여기는 클라이언트 서버에서 실행되므로 이전 요청이 남아있을 수 있기 때문이다 if (req && cookie) { axios.defaults.headers.Cookie = cookie; // 서버일때랑 cookie를 써서 요청을 보낼 때만 headers에 cookie를 넣어준다 } store.dispatch({ type: LOAD_MY_INFO_REQUEST, // user }); store.dispatch({ type: LOAD_POSTS_REQUEST, // post }); store.dispatch(END); await store.sagaTask.toPromise(); // store/configureStore.js > store.sagaTask }); // 이 부분이 Home 보다 먼저 실행됨 ``` 그리고 reducer 또한 문제가 없어 보입니다. case LOAD_MY_INFO_REQUEST: draft.loadMyInfoLoading = true; draft.loadMyInfoDone = false; draft.loadMyInfoError = null; 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; 이어서 saga user 입니다. function loadMyInfoAPI() { return axios.get('/user'); // GET(Browser) } function* loadMyInfo() { try { const result = yield call(loadMyInfoAPI); console.log(result); yield put({ type: LOAD_MY_INFO_SUCCESS, data: result.data, }); } catch (err) { console.error(err); yield put({ type: LOAD_MY_INFO_FAILURE, error: err.response.data, }); } } routes/user 입니다. router.get('/:userId', async (req, res, next) => { try { const fullUserWithoutPassword = await User.findOne({ where: { id: req.params.userId }, attributes: { exclude: ['password'], // 원하는 정보만 가져오거나 가져오지 않겠다 / 현재: pw 빼고 다 가져오겠다 }, include: [ { model: Post, attributes: ['id'], }, { model: User, as: 'Followers', attributes: ['id'], }, { model: User, as: 'Followings', attributes: ['id'], }, ], // 가져올 정보중 뺄 것들 }); if (fullUserWithoutPassword) { const data = fullUserWithoutPassword.toJSON(); data.Posts = data.Posts.length; // 개인정보 침해 예방 data.Followers = data.Followers.length; data.Followings = data.Followings.length; res.status(200).json(data); } else { res.status(404).send('존재하지 않는 사용자입니다.'); } } catch (err) { console.error(err); next(err); } }); 추가로 middleware 입니다. exports.isLoggedIn = (req, res, next) => { if (req.isAuthenticated()) { next(); // 비어있으면 다음 미들웨어로 간다 } else { res.status(401).send('로그인이 필요합니다.'); } }; exports.isNotLoggedIn = (req, res, next) => { if (!req.isAuthenticated()) { next(); // 비어있으면 다음 미들웨어로 간다 } else { res.status(401).send('로그인하지 않은 사용자만 접근이 가능합니다.'); } }; 살펴본 결과 로직은 문제가 없어보이는데 혹시 front에서 getServerSideProps 문법이 강의와 다른데 라이브러리 사이트를 보고 적용했던겁니다. 제가 너무 헤매고 있어서 보시고 조언 주신다면 감사하겠습니다... network 401
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
context.req에 대해서 질문이 있습니다.
안녕하세요. 이번 강의에서 설명하신게 이해가 잘 되지 않아서 질문드립니다. 위 코드가 강의에서 설명하신 코드인데요(콘솔로그 부분 제외) 1. getServerSideProps가 프론트 서버에서 실행되는 코드라고 하셨는데, 이는 back 디렉토리에 백엔드 서버 코드의 (req,res,next)=>{ ... return res.status(200).send('ok') } 처럼 프론트 서버의 특정 라우터로 요청이 갔을 때 실행되는 부분이라고 이해했는데 맞나요..? 2. 그래서 이것을 확인해보기 위해서 req.url과 req.method를 콘솔로 찍어봤는데 첫 새로고침 때는 위와 같이 나와서 생각한게 맞구나 싶었는데, 다른 페이지를 갔다가 오면 위처럼 req.url이 다르더라고요.. 무슨 차이가 있는건지 궁금합니다... 3. getServerSideProps 안에 작성된 코드가 프론트 서버에서 실행되는 코드라면 context.req 는 항상 true가 아닌가요..? 요청이 왔을 때만 서버가 실행된다고 생각했고, const {cookie} = context.req.headers; axios.defaults.headers.Cookie = ""; if (cookie) { axios.defaults.headers.Cookie = cookie; } 이렇게 코드를 작성해도 되는게 아닌가 싶어서 질문드립니다. 혹시 context.req 가 true가 아닐 경우가 있으면 간단한 예를 들어주실 수 있을까요?? 4. 마지막으로 프론트 서버는 어디서 온건가요...? .next - server 에 있는게 프론트 서버인가요??? 해당 서버는 pages의 파일들을 수정하면 알아서 설정되는 것인지도 궁금합니다.
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
로그인 질문(로그인하지 않은 사용자만 접근이 가능합니다)
위와 같이 로그인을 하지 않은 상태입니다. 그런데 로그인을 하면 저렇게 401 에러가 뜹니다. 뭐가 잘못됬는지 감이안와서 헤매고 있는데 조언좀 주세요 ㅠ 401 에러 이외엔 에러 메세지가 따로 없습니다. ```javascript // routes/middlewares.js exports.isLoggedIn = (req, res, next) => { if (req.isAuthenticated()) { next(); // 비어있으면 다음 미들웨어로 간다 } else { res.status(401).send('로그인이 필요합니다.'); } }; exports.isNotLoggedIn = (req, res, next) => { if (!req.isAuthenticated()) { next(); // 비어있으면 다음 미들웨어로 간다 } else { res.status(401).send('로그인하지 않은 사용자만 접근이 가능합니다.'); } }; ``` ```javascript routes/user.js router.post('/login', isNotLoggedIn, (req, res, next) => { passport.authenticate('local', (err, user, info) => { if (err) { console.error(err); next(err); } if (info) { return res.status(401).send(info.reason); // client로 응답을 보내줌, 401: 허가되지 않음, 403: 금지 } 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'], // 원하는 정보만 가져오거나 가져오지 않겠다 / 현재: pw 빼고 다 가져오겠다 }, include: [ { model: Post, }, { model: User, as: 'Followers', }, { model: User, as: 'Followings', }, ], // 가져올 정보중 뺄 것들 }); return res.status(200).json(fullUserWithoutPassword); }); })(req, res, next); }); // 로그인 전략 실행 ``` ```javascript // front/components/AppLayout.js <LoggedFixed>{me ? <UserProfile /> : <LoginForm />}</LoggedFixed> ```
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
어제까지 잘되다가 갑자기 mysql에서 에러가 터지네요 ㅜㅜ
아무리 찾아봐도 모르겠어서 올립니다 ㅜㅜ 서버실행중 ConnectionRefusedError [SequelizeConnectionRefusedError]: connect ECONNREFUSED 127.0.0.1:3306 해당 에러떠서 mysql이 start안됬나싶어 터미널에서 mysql.server start해봤는데 ERROR! The server quit without updating PID file (/opt/homebrew/var/mysql/LeeJaeHoonui-MacBookAir.local.pid). 위와 같은 에러가 뜹니다. 또한 mysql -uroot했을 시 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)가 뜹니다. 어제까지 잘되다가 갑자기 왜이러는 걸까요 ㅜㅜ mac m1입니다 해결방법 알 수 있을까요?
- 해결됨[리뉴얼] React로 NodeBird SNS 만들기
댓글작성 도중 해결안되는 에러가 있어 여쭤봅니다...
댓글 등록하고 버튼 눌렀을때 User 값이 안들어오는 것처럼 에러가 뜨는데 그 상태에서 바로 새로고침하면 값이 들어가있네요 분명 통신과정에서 올바르게 include한 전체 값을 들고오는게 맞는데 뭐가 문제인걸까요....?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
route 53 질문있습니다.
위와 같이 도메인 이름을 하면 제로초님걸로 들어가지는데 따로 제가 이름을 다르게 만들어야되나요? 아래는 현재 레코드 입니다.
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
db 관련 질문입니다
안녕하세요 제로초님 Product를 Cart에 추가할 때 Cart에 기존 아이템 존재시 product의 totalPrice와 quantity만 증가시켜주고 아닐시 새로운 product를 만들도록 해보았습니다. ㄴ 우선 Cart에 처음으로 product를 추가하고 이후 Cart에 기존 아이템 존재시 product의 totalPrice와 quantity만 증가시켜주는 것 까지는 정상적으로 db에 저장하는 것 까지는 되었습니다. 에러 문제는 그 해당하는 상품의 다른 사이즈를 추가할 때부터 발생했습니다. 한 테이블에 ProductId와 UserId 가 같은 값을 가진 상태로 또 추가가 되니 발생하는 오류인 것 같았습니다. 찾아본해결 https://github.com/sequelize/sequelize/issues/3220 에 따라서 unique: false 를 추가해서 다시 db에 저장해보니 정상적으로 추가가 되긴 했습니다. 다만 기존 Product의 같은 사이즈를 또 추가할 때 기존 데이터에서 quantity와 totalPrice가 증가되어 저장하는게 아니라 새로운 데이터가 만들어지면서 추가되어버립니다 이럴 때 ProductId와 UserId를 한 테이블에 여러 번 쓰면서 quantity와 totalPrice만 증가시켜서 저장할 수는 없는지 궁긍합니다.
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
회원가입 시 서버 에러와 mysql DB 관련 에러
회원가입 시 서버쪽에서 에러가 납니다. database_production이 존재하지 않는다해서 database_production을 생성했더니 이번엔 파라미터가 undefind 입니다. database_production이 어디서 나온건지 당황스럽고;; react-nodebird DB를 쓰고 싶은데 어찌해야될지 모르겠습니다. 강의를 보다보니 저도 같은 에러가 생겨서 DROP DATABASE `react-nodebiird`를 했고 이후 다시 npx sequelize db:create를 했습니다. 그런데 아래와 같이 보니 table이 없습니다.. 조언좀 주세요 ㅠ
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
팔로잉 목록과 팔로워 목록을 가져올 때 궁금한게 있습니다.
안녕하세요. 로그인 시 include로 팔로잉 목록과 팔로우 목록을 가져올 때 attributes로 id만을 가져오도록 했음에도 위처럼 가장 아랫줄에 있는 Follow 도 같이 가져와지는데, N:M 관계에서 설정하면서 생긴 모델(테이블)을 통째로 항상 같이 가져오게 되는건가요...?? 해당 정보가 필요한 상황이 아님에도 가져오게 되는건 데이터 낭비가 아닌가라고 생각이 들어서요... 이번 강의에서 프로필 페이지에서 별도로 팔로워 유저와 팔로잉 유저를 요청한 것도 데이터의 낭비를 막기위함이라고 생각했어서요.. 혹시 Follow 데이터를 가져오지 않을 수 있으면 알려주시면 감사하겠습니다.
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
인스턴스 연결 에러
ssh -i "nodebird-access-key.pem" ubuntu@ec2-3-38-96-64.ap-northeast-2.compute.amazonaws.com 해당 명령어를 그대로 복사 뒤 access-key가 있는 위치에서 실행했지만 ``` Warning: Identity file nodebird-access-key.pem not accessible: No such file or directory. ubuntu@ec2-3-38-96-64.ap-northeast-2.compute.amazonaws.com: Permission denied (publickey). ``` 위와 같은 에러가 생깁니다. 구글링을 해봐도 해당 에러에 관한 설명은 많으나 봐도 제가 이해를 못해 해결을 못하고 있습니다