월 15,400원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
보안이 필요한 파일 관련 질문
안녕하세요. 먼저 좋은 강의 감사드립니다.아래와 같은 질문이 있어 문의 드립니다.강의에서 설명 주신 것처럼 S3를 이용하여 file 자료를 관리하려고 합니다. 하지만 file 자료가 보안이 필요하여 Client에서 바로 접근은 정책적으로 S3에 막고, 백엔드 서버를 거쳐서만 Client에 전송하려고 합니다. 이 경우 어떤식으로 해야 할 지 문의드립니다. (아래 경우 중에 어떤 방법인가요? 다른 좋은 방법이 있다면 설명 부탁드립니다.)[ Client에서 File Download 요청 시 (Get Restful API) ](경우 1) 서버에서 S3의 파일을 서버(EC2)로 다운로드 한 후에 다시 서버에서 해당 저장파일을 load해서 Client쪽에 보내서 받는 경우 -> 이 경우라면 중간 중간에 어떤식으로 파일들을 load하고 API에 실어서 보내야 하나요? 백엔드 서버에 일단 파일로 저장하고 그것을 다시 Load해서 보내나요, 아니면 S3에서 읽어온 메모리를 바로 응답에 실어서 보낼 수도 있나요?(라이브러리나 개략적인 코드 순서부탁드립니다.) 그리고 이 경우 서버에 무리가 갈 것 같은데 어떤식으로 조절해야 하나요?(경우 2) 서버에 File 요청이 왔을 경우 임시 토큰(?)을 발행하여 한번만 S3에서 다운로드 받게 하여 서버 부하를 줄이는 방법 (이런 방법이 가능한지는 모르겠어요.)cf. 위 방법 말고 실무에서 하시는 방법이 있으면 말씀 부탁드립니다. (보안관련 File관리 (서버 부하 고려))
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
안녕하세요! 에러가 해결이 안되서 문의 드립니다!
<Error> <Code> AccessDenied </Code> <Message> Invalid according to Policy: Extra input fields: content-type </Message> <RequestId> GQSZRQNAQMXMXXVG </RequestId> <HostId> UpJDG/uFesEIyfK0XlzwBoFrC9oUY9zNKokwWwZl7mkd+SziH4WbJbsUfT7SjJCWyg+fIR0r5v4= </HostId> </Error>s3로 전송하면 403에 위와 같은 에러가 리턴되는데 원인이 뭘까요??? presigned까지 잘 받아와지고, s3로 전송하는 formdata의 데이터는 아래와 같습니다.['key', 'row/e2af34f5-f3d6-442c-994f-353729ffeb15.png'] ['bucket', 'image-upload-tutorials'] ['X-Amz-Algorithm', 'AWS4-HMAC-SHA256'] ['X-Amz-Credential', 'AKIA3KPTOAZFKGL355XY/20220905/ap-northeast-2/s3/aws4_request'] ['X-Amz-Date', '20220905T173547Z'] ['Policy', 'eyJleHBpcmF0aW9uIjoiMjAyMi0wOS0wNVQxNzo0MDo0N1oiLC…9LHsiWC1BbXotRGF0ZSI6IjIwMjIwOTA1VDE3MzU0N1oifV19'] ['X-Amz-Signature', 'c433498a287025e7b4d2dd5935fe1c4fd6d04a8afd79cfd4434dcfd1b044996a'] ['Content-Type', 'image/png'] ['file', File]
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
질문이 하나 있습니다~
에러 json으로 보내실 때try 문에서 if(!id) return res.status(400).json({}) 으로 보내는 것과throw new Error('') 로 보낸 뒤 catch에서 res.json하는게 좀 다를까요 ?
- 해결됨이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
onSubmit 이미지 업로드에서 업로드 성공 또는 에러 메세지가 발생되지 않습니다
일단 저는 node.js 서버 환경이 아닌 Springboot 서버 환경이고 front에서 http://localhost:8080/images api로 이미지를 잘 전달 합니다! 그런데 한 번 전달하게 되면이미지 성공 toast알림이 뜨지 않고 또한 다시 초기화를 해주는 쪽 블럭으로 넘어가지 않는 것 같습니다코드는 강사님꺼 그대로 가져다 사용하였고 server쪽 url 호출시 cors문제가 있어서 package.json에 proxy 설정해주었고 백엔드 서버에 1번은 제대로 가져오는 것까지 확인하였습니다. < 이게 백엔드에서 file에 대한 정보 찍어봤을 때 나온 결과값입니다.import React, { useState } from 'react' import { toast } from "react-toastify" import axios from 'axios'; ... [생략] const onSubmit = async (e) => { e.preventDefault(); const formData = new FormData(); formData.append("image", file) console.log(formData); try { const res = await axios.post("http://localhost:8080/images", formData,{ headers: { "Content-Type" : "multipart/form-data" }, onUploadProgress: (e) => { setProgress(Math.round(100 * e.loaded/e.total)); }, }); toast.success("success!! 이미지 업로드 성공"); setTimeout(() => { setProgress(0); setFileName(defaultUpload); setFileUrl(null); }, 3000); } catch (error) { toast.error(error.message); setProgress(0); setFileName(defaultUpload); setFileUrl(null); console.error(error); } }왜 try 부분에서 성공시/에러시에 대한 아웃풋을 넘겨주지 않는지 잘 모르겠습니다 ㅠ 답변 부탁드릴게요현재까지 수강중인 내용은 db를 통해 이미지 정보 저장하기까지 들었습니다
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
DB에서 불필요한 데이터 제거하고 전송하기
현재 프론트쪽으로 document의 모든 데이터( _id, createdAt, updatedAt, _v 포함)를 보내주는데, 보내주고 싶지 않은 데이터만 빼서 보내주려면 어떻게 해야하나요? 특히, user라는 document가 있을경우, 많은 필드 중에서 password 정보만 빼고 보내준다던가, 이런 경우요
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
단순히 이미지만 보내는게 아닐때
회원가입을 한다고 가정할때, 각종 다른 정보랑 프로필 이미지를 post 한다고 할때는 어떠한 방식으로 보내야 하는건가요?
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
보너스 섹션 배포
안녕하세요 강의 잘 들었습니다 보너스 섹션 배포 방법?은 아직 강의가 만들어지지않은건가요?
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
axios 통신 오류
안녕하세요. 로그아웃 기능을 구현하는데 axios통신이 되지 않아서 질문드립니다. 회원가입까지는 되고 이후에 toolbar에서 로그아웃을 클릭하면 첨부한 사진과 같이 axios 통신에러가 나는데 왜 그런지 잘 모르겠습니다.... 저는 로그아웃을 patch로 하지 않고 서버와 클라이언트에서 모두 post로 구현을 했습니다. patch로 바꿔바도 결과가 그대로 오류가 나옵니다.... 코드까지 올리겠습니다.. AuthContext.js import React, { createContext, useState, useEffect } from "react"; import axios from "axios"; export const AuthContext = createContext() //context 객체 만들기 export const AuthProvider = ({children}) => { //provider const [user, setUser] = useState() //유저 로그인 정보를 받기 위한 저장소 useEffect(()=>{ if(user) axios.defaults.headers.common.sessionid=user.sessionId //user가 있을 경우 기본값으로 header에 sessionId를 입력 else delete axios.defaults.headers.common.sessionid //user가 없는 경우 sessionid를 삭제 }, [user]) return ( <AuthContext.Provider value={[user, setUser]}> {/*provider를 통해 state와 set함수를 넘겨줌.*/} {children} </AuthContext.Provider> ) } toolbar.js import React, { useContext } from "react"; import { Link } from "react-router-dom"; import { AuthContext } from "../context/AuthContext"; import axios from 'axios' const ToolBar = () => { const [user, setUser] = useContext(AuthContext) //context 사용을 설정 const Logout = async()=>{ try{ await axios.post('/users/logout') //로그아웃으로 post setUser() // console.log("로그아웃 완료") }catch(err){ console.log(err) } } return ( <div> <Link to='/'> <span style={{ marginRight: 10 }}>홈</span> </Link> {user ? //이전에 공유하는 user가 존재 유무 (<span onClick={(e)=>{Logout()}}>로그아웃</span>) : (<> <Link to='/auth/login'> <span style={{ marginRight: 10 }}>로그인</span> </Link> <Link to='/auth/register'> <span >회원가입</span> </Link> </>) } </div> ) } export default ToolBar userRouter.js const { Router } = require('express') const userRouter = Router() const User = require('../models/User') const { hash, compare } = require('bcryptjs') const mongoose = require('mongoose') userRouter.post('/register', async (req, res) => { try { if (req.body.password.length < 6) { throw new Error("6자리 이상으로 비밀번호를 입력하세요.") } if (req.body.username.length < 3) { throw new Error("3자리 이상으로 유저 이름을 입력하세요.") } const hashedPassword = await hash(req.body.password, 10) //비밀번호를 hash로 만들어 줌 const user = await new User({ //user 객체를 생성 name: req.body.name, username: req.body.username, hashedPassword: hashedPassword, //입력받은 req데이터를 객체에 저장. sessions: [{createdAt: new Date()}] }).save() const session = user.sessions[0] //회원가입이기 때문에 무조건 첫번째로 생성된 세션을 기준으로 잡음. res.json({ message: "회원가입 완료", sessionId: session._id, name: user.name }) } catch (err) { res.status(400).json({message: err.message}) } }) userRouter.post('/login', async (req, res)=>{ try{ const user = await User.findOne({username: req.body.username}) //mongoose의 내장함수로 요청정보에 맞는 유저를 찾는다. const isValid = await compare(req.body.password, user.hashedPassword) //요청된 비밀번호와 해쉬번호를 비교 if(!isValid) throw new Error("잘못된 입력입니다.") user.sessions.push({createdAt: new Date()}) //유저의 세션을 추가 const session = user.sessions[user.sessions.length-1] //session은 가장 최근에 만든 세션을 기준으로 잡음. await user.save() //user모델을 DB에 저장 res.json({message: "로그인 성공!", sessionId:session._id, name:user.name}) }catch(err){ res.status(400).json({message: err.message}) } }) userRouter.post('/logout', async (req, res)=>{ try{ //미들웨어를 갔다 온 뒤 처리 if(!req.user) throw new Error("유효하지 않은 세션입니다.") await User.updateOne({_id:req.user.id}, //저장된 user의 id와 스키마의 id 같은 것을 찾아서 업데이트 함. {$pull: {sessions: {_id:req.headers.sessionid}}} //세션들 중 로그아웃할 세션id와 같은 세션을 pull을 통해 삭제함 ) res.json({success: "성공!"}) }catch(err){ res.status(400).json({message: err.message}) } }) module.exports = { userRouter }
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
s3 ClientConfiguration 옵션 질문
server/aws.js 에서는 s3 인스턴스 생성할 때 ClientConfiguration 옵션 객체에 accesskey랑 secretkey를 넣어줬는데요 lambda/index.js 에서는 안해줘도 되나요? 어떻게 인증이 되는건가요?
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
이미지 파일은 결국
업로드 요청한 이미지 파일들은 DB가 아니라 서버에 저장하고, 이미지 파일 GET 요청을 하면 DB에 들어있는 이미지 이름을 불러와서 이를 가지고 서버에 있는 이미지들을 식별하여 찾아내서 클라쪽으로 보내주는 방식인건가요? DB에 이미지를 저장하지 않고 서버에 저장하는 거죠? 현업에서 이런 방식으로 작업하는건가요?
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
이 강의에서 가르치는 이미지 관리 방식을 뭐라고 하나요?
안녕하세요. 강의 잘 수강하였습니다. 이 강의에서 나온 것처럼 이미지를 w160, w600 raw등으로 분류하여 여러 이미지를 저장하고, 필요한 사이즈에 맞는 이미지를 보여주는 방식을 뭐라고 칭하는지 궁금합니다.
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
소스코드 github주소는 없을까요?
React 작업에서 논리적인 버그가 발생했는데, 원인을 찾지 못하고 있습니다. 소스코드 github주소가 있으며 비교하면서 디버깅하기 좋을 것 같습니다. 감사합니다.
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
강의자료는 어디서 받을수 있나요??
강의자료는 어디서 받을수 있나요??
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
프로그래스 바 진행도
axios의 onUploadProgess 메서드를 이용해 진행률을 표시할 수 있는 좋은 정보 감사합니다. 궁금한점은 일반 FileReader에서 제공하는 progress 이벤트에서는 1%~100%를 차례대로 받아오지 않고 무조건 100%로만 받아와 지던데, 만약 로컬에서 이미지를 미리보기로 띄우기위한 프로그레스 바를 만든다고하면 어떻게 진행률을 표시해야 하나요?? 로컬에서 받아와야하니 axios의 메서드를 쓰지 못해 난감하네요..
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
Presigned URL이 발급되고 받은 정보로 업로드 요청시 403 Forbidden이 뜹니다.
S3 버킷에는 강의에 있는 것처럼 CORS 및 정책이 있는 사용자등도 모두 적용되었습니다. Presigned URL까지는 정상적으로 발급되고 해당 URL로 Post를 통해 업로드시 아래와 같이 에러가 발생합니다. [1] CORS [ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "POST", "PUT" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [] } ] [2] 버킷정책 { "Version": "2012-10-17", "Id": "Policy1643682083325", "Statement": [ { "Sid": "Stmt1643681984914", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::image-upload-test/raw/*" } ] } [3] Error(Client Side) POST https://s3.ap-northeast-2.amazonaws.com/image-upload-test net::ERR_CONNECTION_ABORTED POST https://s3.ap-northeast-2.amazonaws.com/image-upload-test 403(Forbidden) 혹시 어떤 부분이 잘못 되었을까요?
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
유효성검사
서버에서 username과 password에 대한 유효성검사를 하는 로직을 작성했는데 클라이언트에서도 처리를 해줘야하는 건가요?
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
이미지 업로드를 리액트 드롭존으로 구현하려고 하는데 잘안되서요
안녕하세요 김시훈 강사님 질문이 있습니다. 질문1 메인 페이지의 파일 업로드 컴퍼넌트 로직이 좀 이상해서 봐주시면 감사요 특히 폼데이터 설정 부분이 폼 데이터를 지우고 다시 설정하는데 좀더 좋은 방법이 있을까요? // set file data to form Object and axios request to file upload to server const onSubmit = async (e) => { e.preventDefault() console.log('submit 함수 실행 check') const formData = new FormData() // if (files != null) { // console.log("files : ", files); // for (let file of files) { // formData.append("image", file); // } // } else { // alert("파일을 선택해 주세요"); // return; // } try { await Promise.all( [...files].map((file, index) => { formData.delete('image'); formData.append("image", file); const res = axios.post("/upload", formData, { headers: { 'Content-Type': 'multi/form-data' }, onUploadProgress: (e) => { setPercent((prevData) => { const newData = [...prevData]; newData[index] = Math.round((100 * e.loaded) / e.total); return newData; }) } }) console.log({ res }) }) ) await toast.success('success!!') setTimeout(() => { setPercent([]); setFileNames([]); }, 2000) } catch (err) { toast.error('fail!') console.log(err) } } 질문2 드롭존 페이지에서 파일 업로드가 안되는데 원인을 잘 모르겠습니다 한번 봐주시면 감사하겠습니다. github: https://github.com/hyunsokstar/making-daum-file-upload server 실행 명령어 npm run dev front 서버 실행 명령어 npm start main page: http://127.0.0.1:3000/main dropzone page: http://127.0.0.1:3000/dropzone노트 정리: http://www.skilnote-for-react.co.kr/wm/myshortcut/making-daum-file-upload/27
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
error: (intermediate value).map is not a function
ImageList.js import React, { useContext } from 'react'; import { ImageContext } from '../context/ImageContext'; const ImageList = () => { const { images, myImages, isPublic, setIsPublic } = useContext(ImageContext); console.log(myImages); const imgList = (isPublic ? images : myImages).map((image) => ( <img alt="" key={image.key} style={{ width: '100%' }} src={`http://localhost:8000/uploads/${image.key}`} /> )); return ( <div> <h3 style={{ display: 'inline-block', marginRight: 10 }}> Image List({isPublic ? '공개' : '개인'} 사진) </h3> <button onClick={() => setIsPublic(!isPublic)}> {(isPublic ? '개인' : '공개') + ' 사진 보기'} </button> {imgList} </div> ); }; export default ImageList; error: (intermediate value).map is not a function ImageContext.js > const [myImages, setMyImages] = useState([]); myImages 가 문제인거 같은데..함수가 아니라니..원인을 알 수가 없네요 ~ㅠㅠ
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
node js 버전이 어떻게 되나요?
맞춰서 하고 싶은데 버전을 모르겠어서 여쭤봐요..!
- 미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
클라이언트측 오류처리 에러
로그인 창에서 서버측 에러들은 정상적으로 홈페이지로 돌아가서 toast 에러창이 뜨는데, 클라이언트측의 조건에 일치할때는 위와같은 에러가 발생합니다. (client) (server)