티스토리 뷰
회원들이 자유롭게 게시물을 올릴 수 있다면 그것이 게시판아니겠습니까 만들어봅시다.
근데 게시판 기능은 이미 다 만들어놨는데요
CSS 디자인만 게시판이 아닐 뿐 write/list 페이지 보니까 게시판 맞습니다.
다만 지금은 누구나 게시물을 삭제가 가능한데 이걸 본인 글만 삭제가능하게 제한을 두면 되겠습니다.
그러려면 유저가 몇명 필요해서 일단 회원가입기능부터 만들어봅시다.
회원가입기능 어떻게 만들죠
이런건 알아서 만들 수 있지 않겠습니까
그냥 <form> 만들고 거기다가 아이디/비번 입력할 수 있게 만듭니다.
그리고 전송 누르면 서버로 보내고, 그걸 DB에 저장시키면 끝 아니겠습니까.
여기까지 배운 이상 여러분이 혼자 못만들 기능은 없습니다.
그래서 저는 login.ejs에 가입창을 하나 만들어놨습니다.
(login.ejs)
<div class="container mt-4">
<form action="/register" method="POST">
<div class="form-group">
<label>아이디</label>
<input type="text" class="form-control" name="id">
</div>
<div class="form-group">
<label>비번</label>
<input type="password" class="form-control" name="pw">
</div>
<button type="submit" class="btn btn-danger">가입</button>
</form>
</div>
실은 로그인창이랑 똑같음 근데 /register로 POST요청하는 것만 다릅니다.
아무튼 이거 전송하면 입력한 아이디와 패스워드로 가입이 되도록 합시다.
그럼 서버에다가 코드를 어떻게 짭니까.
알아서 해보도록 합시다.
app.post('/register', function (요청, 응답) {
db.collection('login').insertOne({ id: 요청.body.id, pw: 요청.body.pw }, function (에러, 결과) {
응답.redirect('/')
})
})
저는 누군가 /register로 POST 요청을 하면
login이라는 컬렉션에다가 게시물하나를 추가하라고 했습니다.
{id : 입력한아이디, pw : 입력한패스워드} 이런 게시물이 저장되겠네요.
그리고 _id는 자동으로 부여되는걸 그대로 사용할겁니다.
그럼 이제 아이디/비번을 tester/1234 이렇게 입력하고 가입버튼을 누르면
MongoDB Atlas에 이런 식으로 저장이 되어있겠군요
별거 아닙니다
Q. 회원의 _id는 왜 0,1,2 이런 숫자로 만들어서 저장안하죠?
A. 원래 이런걸 Auto increment 이용해서 정수로 넘버링을 해서 저장할 필요는 없습니다.
SQL의 잔재 이런건데.. 실은 정수로 번호매기는 기능이 필요한 경우는 정말 없기 때문입니다.
회원 번호를 정수로 만들어버리면 총 회원이 몇명인지 이런것도 유추하기 쉽겠고 장점이 없어보입니다.
생각해보십시오 굳이 글번호, 회원번호를 정수로 기록해둘 이유가 없지않습니까. 있으면 알려주십시오
(참고1) 아이디 중복체크는 어떻게할까요?
당연히 DB에 저장시키기 전에 한번 검사를 거치는게 좋겠군요.
1. 만약 DB에 id가 test인게 이미 있으면 가입안된다고 메세지를 띄우기
2. 그게 아니면 DB에 저장시키기
이게 끝일 것 같은데요 여러분 if문법 아시지 않습니까. 모른다면 자바스크립트를 공부할 때입니다.
(참고2) 아이디는 알파벳과 숫자로 구성되어있는지 이런건 어떻게 검사할까요?
자바스크립트 잘하시면 프론트엔드에서도 거를 수 있지만
서버에서도 입력한 아이디가 이상한 문자면 걸러주는 코드를 작성해두는게 좋습니다. 역시 if문이 필요합니다.
이거 말고도 비번 길이라든지 여러가지 제약을 걸어도 되겠죠?
(참고3) 간단히 보여드리기 위해 암호화는 안했으나
비밀번호를 저장할 땐 난수로 바꿔서 DB에 저장하고 로그인시에도 난수로 바꿔서 비교하셔야합니다.
이것도 쉽게 암호화해주는 라이브러리들이 매우 많습니다.
글 주인만 삭제가능하게 만들어봅시다
지금은 글발행할 때 제목, 날짜, _id 이것만 저장하고 있습니다.
그러면 안되겠군요. 누가 발행했는지도 함께 저장해야 나중에 주인만 삭제가능하게 만들 수 있지 않을까요.
▲ 그래서 작성자라는 항목에 작성자의 _id를 집어넣는겁니다.
이건 여러분의 글발행하는 코드를 고치면 됩니다.
요청.user 하면 로그인한 유저의 개인정보들이 가득 담겨있다고 했죠?
(이 정보들은 deserializeUser() 이 함수에서 제공하고 있고요)
그럼 글 발행할 때 요청.user._id 이것도 저장하면 됩니다. 끝
이거 말고도 유저의 _id, 아이디명, 이름 있으면 유저 이름도 함께 저장하면 좋습니다.
근데 여기서 궁금한 점이 하나 생깁니다.
. 유저 아이디와 _id 이런거 동시에 저장할 필요 없는거 같은데여?
넹 맞습니다 유저의 _id를 알면 다른 컬렉션에서 조회해보면 아이디를 알 수 있으니까
유저의 _id만 저장해두면 끝 아니겠습니까.
근데 싫습니다. 전부 게시물과 함께 저장해버릴거임
게시물에다가 유저이름, 아이디 이런걸 다 저장해두면 이게
글쓴이 이름과 아이디가 필요해질 때 다른 컬렉션을 굳이 검색할 필요가 없기 때문에
DB 검색횟수를 줄일 수 있어서 성능적으로 이득이라 그렇습니다. 다만 하드용량은 늘어나겠지만요.
하드용량을 희생해서 검색성능을 높일 수 있다면 그게 이득 아니겠습니까.
이걸 denormalizing이라고 하는데 NoSQL 데이터베이스들은 항상 이런 식으로 데이터를 저장하는걸 권장합니다.
그래서 자주 바뀌지 않는 아이디 이런 정보들은 필요한 게시물들에 함께 저장해두면 좋습니다.
단점 : 나중에 유저 아이디를 바꾸고 싶어하면 그걸 쓰고 있는 게시물들을 다 찾아서 바꿔줘야하겠군요. 이게 단점입니다.
옛날에 SQL하던 분들은 싫어할 수 있습니다.
따로 denormalizing 검색해보시면 여러 관습들을 배울 수 있습니다.
그래서 게시물 발행하는 POST 요청처리하는 코드를 이렇게 바꿨습니다.
한 곳 바꿈
app.post('/add', function (요청, 응답) {
console.log(요청.user._id)
응답.send('전송완료');
db.collection('counter').findOne({ name: '게시물갯수' }, function (에러, 결과) {
var 총게시물갯수 = 결과.totalPost;
var post = { _id: 총게시물갯수 + 1, 작성자: 요청.user._id , 제목: 요청.body.title, 날짜: 요청.body.date }
db.collection('post').insertOne( post , function (에러, 결과) {
db.collection('counter').updateOne({ name: '게시물갯수' }, { $inc: { totalPost: 1 } }, function (에러, 결과) {
if (에러) { return console.log(에러) }
})
});
});
});
▲ 게시물 저장할 때 { 작성자 : 요청.user._id } 이것도 저장하라고 바꿨습니다.
심심하면 날짜 이런것도 저장하셈
자바스크립트로 new Date() 이렇게 쓰면 그 자리에 날짜데이터가 남습니다. 그거 그대로 DB에 저장하면 날짜 저장 끝임
게시물 삭제기능 업그레이드
지금은 개나소나 삭제가 가능한데
내 게시물만 삭제 가능하도록 만들려면 삭제기능을 어떻게 바꿔야되겠습니까.
7번 게시물을 삭제하라~라는 요청이 들어오면
1. 지금 삭제요청중인 유저의 요청.user._id를 까봐야하지 않을까요?
2. 그리고 그게 7번 글에 저장되어있는 작성자 정보랑 일치하면 삭제해야합니다.
app.delete('/delete', function (요청, 응답) {
요청.body._id = parseInt(요청.body._id);
//요청.body에 담겨온 게시물번호를 가진 글을 db에서 찾아서 삭제해주세요
db.collection('post').deleteOne({_id : 요청.body._id, 작성자 : 요청.user._id }, function (에러, 결과) {
console.log('삭제완료');
console.log('에러',에러)
응답.status(200).send({ message: '성공했습니다' });
})
});
▲ 삭제요청할 때 예전엔 { _id : 요청.body._id } 이거 글번호만 확인하라고 해놨는데
{ 작성자 : 지금로그인한사용자의_id } 이것도 가지고 있으면 삭제하라고 업그레이드 해놨습니다.
그러면 사용자1은 사용자2가 발행한 게시물 삭제가 불가능합니다.
'Node.js' 카테고리의 다른 글
Node.js + MongoDB Google Cloud로 사이트 배포하기($300 무료 크레딧) (0) | 2023.05.23 |
---|---|
Node.js API들을 라우터로 관리하자 (0) | 2023.05.22 |
Node.js +_MongoDB 검색3(colection.aggregate(), $regex) (0) | 2023.05.22 |
Node.js + MongoDB 검색2(MongoDB index만들기) (0) | 2023.05.22 |
Node.js + MongoDB 검색(Query형식 GET로 처리하기) (0) | 2023.05.22 |