Javascript
Node.js
Express.js
MySQL
.
├── README.md
├── docs
│ ├── balsamiq-wireframes-2022_05_26.pdf
│ ├── balsamiq-wireframes-2022_05_31.pdf
│ ├── yam-create-2022-06-09.sql
│ └── yam-create.sql
├── pages
├── yam-client (클라이언트)
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── node_modules
│ ├── public
│ │ ├── add-user.png
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── login.png
│ │ ├── logout.png
│ │ ├── manifest.json
│ │ ├── price-tag.png
│ │ ├── robots.txt
│ │ ├── setting.png
│ │ └── write.png
│ └── src
│ ├── App.css
│ ├── App.js
│ ├── __tests__
│ │ └── App.test.js
│ ├── index.js
│ ├── logo.svg
│ └── pages
│ ├── Join.js
│ ├── Login.js
│ ├── Main.js
│ ├── Modify.js
│ ├── Update.js
│ ├── Write.js
│ ├── common
│ │ ├── Footer.js
│ │ ├── Header.js
│ │ └── StyleFormLabel.js
│ └── css
│ ├── Main.css
│ ├── Post.css
│ └── User.css
└── yam-server
│ ├── node_modules
├── config
│ └── config.js
├── controllers
│ ├── index.js
│ ├── post.js
│ ├── tag.js
│ └── user.js
├── images
├── index.js
├── models
│ ├── index.js
│ ├── ingredient.js
│ ├── post.js
│ └── user.js
├── package-lock.json
├── package.json
└── utils
└── file.js
✅ 사용자는 레시피를 등록할 수 있다.
✅ 사용자는 자신이 등록한 레시피를 수정할 수 있다.
✅ 사용자는 자신이 등록한 레시피를 삭제할 수 있다.
✅ 사용자는 첫 화면에서 최신 레시피를 조회할 수 있다.
✅ 로그인한 사용자는 자신이 작성한 레시피를 조회할 수 있다.
✅ 사용자는 레시피를 등록할 때 요리에 필요한 재료를 태그할 수 있다.
✅ 사용자는 재료 태그 목록에서 태그를 클릭하면 해당 태그가 들어간 레시피 목록을 조회할 수 있다.
✅ 사용자는 이메일, 비밀번호, 닉네임을 입력하여 회원으로 가입한다.
✅ 로그인한 사용자는 자신의 닉네임, 비밀번호를 수정할 수 있다.
❌ 사용자는 OAuth 기능을 사용하여 구글 계정으로 가입할 수 있다.
✅ 사용자는 이메일, 비밀번호를 입력하여 로그인할 수 있다.
❌ 로그인한 사용자는 레시피에 좋아요를 등록할 수 있다.
❌ 로그인한 사용자는 자신이 좋아요를 누른 레시피를 조회할 수 있다.
❌ 로그인한 사용자는 자신이 좋아요를 누른 레시피에서 좋아요를 취소할 수 있다.
❌ 레시피 본문 하단에 이 레시피가 받은 좋아요 수를 확인할 수 있다.
❌ 사용자는 재료 태그 목록에서 태그를 클릭하면 해당 태그가 들어간 레시피 목록을 좋아요 순으로 조회할 수 있다.
약 3주동안 간단한 데이터 CRUD 게시판을 구현했다.
혼자서 프론트엔드와 백엔드 작업을 하느라 왔다갔다 하는게 정신없었지만 그래도 재밌었다. React를 이번에 부트캠프에서 처음 배웠는데 프로젝트를 들어가기 전에 몸풀기로 좋았던 것 같다. 하지만 부트캠프에서 하는 1차 프로젝트와 기간이 겹쳐 마지막 일주일은 거의 작업을 하지 못했다. 특히 기능은 거의 다 만들었지만 CSS가 너무 부실한데, 이는 CSS 라이브러리를 사용했으면 될 걸 그 생각을 하지 못해 퀄리티가 낮아져 아쉽다. 다음 프로젝트를 할 때는 CSS를 좀 더 잘 하도록 공부하고 하고 싶다.
프로젝트를 진행하면서 아쉬웠던 점들을 정리했다.
현재 프로젝트에서는 세션 관리를 통해 로그인한 사용자의 정보를 관리한다. 서버 측에서 로그인 할 때 req.session
에 정보를 저장하고, 클라이언트 측에서 window.sessionStorage.getItem('userInfo')
으로 로그인했는지 여부를 확인해 로그인한 사용자라면 사용자 닉네임과 함께 접속했음을 화면에 표시한다.
하지만 이렇게 세션을 관리하니 서버를 내리고 클라이언트에서 새로고침을 해도 계속 로그인 된 상태로 사용자 닉네임을 띄워주고 있는 이슈가 발생한다.
또한 개발자 입장에선 사용자 정보를 조회하기 쉬워서 좋지만 보안 측면에서도 잘못 처리하고 있다는 생각이 든다. 더 나은 세션 관리를 위해 어떻게 관리해야 할지 공부를 더 해야겠다.
// yam-server/controllers/user.js
const {user} = require('../models')
const STATUS_SUCCESS = 200
const STATUS_JOIN_FAIL = 409
const STATUS_LOGIN_FAIL = 401
const STATUS_WRONG_PASSWORD = 401
const crypto = require('crypto');
module.exports = {
login: async function(req, res) {
const hashedPassword = getHashedPassword(req.body.password)
const userInfo = await user.findOne({
where: {
email: req.body.email
, password: hashedPassword
}
})
if(userInfo) {
req.session.email = userInfo.email
req.session.nickname = userInfo.nickname
req.session.userId = userInfo.id
res.json({
"userInfo":userInfo
})
} else {
res.status(STATUS_LOGIN_FAIL).send("잘못된 사용자 정보입니다.")
}
}
, logout: function(req, res) {
req.session.email = undefined
req.session.nickname = undefined
req.session.userId = undefined
res.status(STATUS_SUCCESS).send()
}
}
// yam-client/App.js
// import logo from './logo.svg';
import './App.css';
import React from 'react';
import Main from './pages/Main';
import Join from './pages/Join';
import Login from './pages/Login';
import Modify from './pages/Modify';
import Update from './pages/Update';
import Write from './pages/Write';
import Header from './pages/common/Header';
import Footer from './pages/common/Footer';
import { Navigate, Route, Routes } from "react-router-dom";
const App = () => {
const isLoggedIn = window.sessionStorage.getItem('userInfo')
return (
<div>
<main>
<Header/>
<section>
<Routes>
<Route path="/" element={<Main/>}/>
<Route path="/join" element={<Join />}/>
<Route path="/login" element={<Login />}/>
<Route element={isLoggedIn ? <Modify /> : <Navigate to="/"/>} path="/modify" />
<Route element={isLoggedIn ? <Update /> : <Navigate to="/"/>} path="/update/:id"/>
<Route element={isLoggedIn ? <Write /> : <Navigate to="/"/>} path="/write"/>
</Routes>
</section>
<Footer/>
</main>
</div>
);
};
export default App;
React를 잘 활용하기 위해서는 화면을 구성하고 있는 각각의 컴포넌트를 잘 만들어 조립해야 하는데 이를 나누고 조립하는 부분이 부족했다. 사실 씨냅스 프로젝트를 진행하면서 팀장님께 이렇게 구성해야 한다고 배웠던지라 레시피얌을 할 땐 생각하지 못했던 부분이었다. 분명히 리액트 수업을 들었을 때 그렇게 처리하라고 배웠던 것 같은데 배운 내용을 잘 실천하지 못해 부끄러웠다.
에러가 발생했을 때 적절한 에러 코드와 알럿 메시지 처리를 했어야 했는데 테스트하면서 누락됐다. 다음엔 기능 만들면서 바로바로 만들어야지.
팀장님이 부트캠프 최종 프로젝트까지 마친 다음에 2차로 팀플을 하는 걸로 하자고 하셨다. 그 전에 좋은 직장에 취업하면 더 좋겠지만^^ 취업 준비를 하면서 팀플도 꼭 참여하고 싶다. 아무리 생각해봐도 에러 잡는게 정말 재밌다.