작업 노트
게시판 시작해봅시다 -4 본문
지난번 포스팅에 이어서 route를 만들겠습니다.
Post 처럼 만들면 되는데, 7가지 기본 Actions(index, show, create, new, edit, update, destroy) 중에서 index와 destroy는 만들지 않겠습니다.
즉, 모든 유저들을 나열하여 보여주는 기능과, 유저를 삭제(회원탈퇴) 기능이 없다는 뜻입니다. CRUD(Create, Read, Update, Delete)중에 Delete이 없는 것이기도 한데, 굳이 모든 데이터에 CRUD를 따르겠다고 생각하시는 분은(바람직한 자세입니다.) 직접 추가하시기 바랍니다. 어렵지 않아요~~
117~125번째 줄 : 유저 생성 view를 보여주는 route입니다. 혹시라도 invalid한 정보가 서버로 전달되면 다시 form으로 되돌려 보내기 위해 formData가 있고, 나머지 에러들을 띄워줄 속성들도 있습니다.
126~131번째 줄 : 유저를 직접 생성합니다. checkUserRegValidation은 밑에 따로 정의한 함수인데, form에 입력한 정보 중 email과 nickname이 겹치는지 아닌지를 알려주는 함수 입니다. 물론 User 스키마에서 email과 nickname이 겹치지 않도록 unique: true를 사용했지만, 단순히 에러를 리턴하기 때문에 custom error를 보여주기 위해 만들었습니다.
132~137번째 줄 : 유저의 profile을 보여주기 위한 route인데, 현재는 아이디만 알면 누구의 정보라도 볼 수 있게 되어 있습니다. 다음번 포스팅에서 자기의 정보만 볼 수 있도록 제한하겠습니다.
138~150번째 줄 : 유저 정보수정 form을 보여주는 route입니다. 항상 edit이나 new는 형식이 많이 비슷하죠.
151~170번째 줄 : chcekUserRegValidation을 사용해서 업데이트 할 정보가 유효한지를 판단합니다. 그리고 정보 업데이트를 실행하기 전에 우선 비밀번호가 맞는지를 확인해야 겠죠(148번째 줄), 그리고 새로운 비밀번호를 입력한 경우에 model의 비밀번호를 교체하고 그렇지 않은 경우에는 모델에서 비밀번호를 빼버립니다.
아 그리고 게시판 시작페이지에서 로그인이 되어 있는 경우 "profile", "logout" 버튼을 보여주고, 로그인이 되어 있지 않은 경우 "login", "sign up" 버튼을 보여줄텐데, 이러기 위해서는 시작페이지로 req.user를 보내서 view에서 로그인이 되어있는지 아닌지를 알 수 있게 해야 합니다. (req.user는 passport package에서 생성하는 개체로, session이 생성될때(로그인할때) 자동 생성되는 개체라는것 기억하시죠?)
게시판의 시작페이지, 즉 index에 user를 전달합니다.
이제 checkUserRegValidation함수를 살펴 봅시다.
이론은 간단합니다. 유저를 새로 등록하거나 유저 정보를 변경하기 전에 DB에 email이 이미 등록되어 있는지, nickname이 이미 등록되어 있는지를 찾아보고 결과가 있으면 에러 메세지를 보내는 것입니다. 근데 Mongoose는 비동기 방식의 함수를 쓴다는 것에서 문제가 있습니다.(읭 왜 갑자기 Mongoose? -> User, Post 모델을 Mongoose package 써서 만들었다는 사실 기억하시죠?)
함수 안에 3개의 함수가 있는 것을 볼 수 있는데, async package를 사용하지 않고 그냥 나열해서 사용할 경우 정상 작동하지 않습니다. 왜냐면 비동기(async)방식으로 진행할 경우 첫번째 함수에서 데이터를 호출하기 전에 두번째 함수가 실행되고, 두번째 데이터를 호출하기 전에 세번째 함수가 실행되고 다음 단계로 넘어가 버리기 때문입니다.(못믿겠으면 한번 해보세요~~)
async.waterfall 이라는 것은 async package에서 제공하는 많은 기능중에 하나인데, 비동기함수들을 동기(sync)함수처럼 사용하게 해 줍니다. 처음 두개의 함수는 []안에 배열로 들어가 있고, 마지막에 따로 나와 있는 함수는 마지막에 실행되거나 중간에 오류가 있을때 실행되는 함수입니다. 배열 안의 함수들은 항상 마지막 parameter로 callback을 가지는데, 이 함수(callback)를 호출하면 다음번 함수가 호출이 되고, 여기에다가 다음 함수에 전달할 값을 넣을 수 있습니다. 여기에서는 isValid하나만 전달하고 있지만 2개 이상도 나열해서 전달 가능합니다. 다만 그 다음 함수에서 callback전에 같은 수의 parameter를 지정해 줘야겠지요.
221, 231번째 줄의 "_id: {$ne: mongoose.Types.ObjectId(req.params.id)}" 도 자세히 살펴봅시다.
유저를 생성, 업데이트 하기 전에 DB에 같은 값의 email, nickname을 살펴보기 위한 함수인데, 업데이트시에 email은 그대로 두고 nickname만 바꾸는 경우가 있을 수 있습니다. 그래서 단순히 DB에 같은 값이 있는지 없는지를 보는 것이 아니라, email이 같지만 id는 다른 경우만 찾아야 합니다.
{$ne: ~~~}는 !=의 의미를 가집니다. 두번째로 아이디가 같은 경우를 찾을때는 단순히 id:req.params.id를 사용하면 됐는데, 이는 mongoose에서 string인 id를 id object로 변환해 주기 때문입니다. DB에서 data들을 살펴보면 사실 id는 단순히 string이 아니라 object임을 알 수 있습니다. 하지만 $ne를 쓰는 경우에는 mongoose가 자동으로 object로 변환을 안해주는지, 제대로 검색을 안해주더라구요. 그래서 생성자를 이용해서 object를 만들었습니다.
남은 것은 login view, user view들인데 어려운 내용이 없으므로 따로 설명하지 않겠습니다. 지난번 post만들때와 같이 header와 footer는 같습니다.
마지막으로 post의 index view를 수정해 줍니다. login이 되어 있으면 logout과 profile 버튼을 보여주고, login이 안되어 있으면 login과 sign up버튼을 보여줍니다.
사용된 css, js 역시 설명하지 않고 파일 첨부만 하겠습니다.
javascript는 form을 서버로 보내기 전에 필요한 값들이 있는지, 비밀번호와 비밀번호 확인 필드의 값이 일치하는지를 확인하는 용도로 쓰였습니다.
우측에 login과 Sign Up 버튼이 생겼습니다. Sign Up을 누릅니다.
회원가입 form이 나타납니다.
입력하지 않은 값이 있는 경우 form이 진행되지 않고 안내가 나옵니다. 이 문구는 front end의 js 파일에서 오는 문구입니다. 서버를 거치지 않고 바로 안내가 나오므로 속도가 빠릅니다.
다른 예를 들어 이미 등록된 email을 또 등록하려고 하면 서버에서 확인후 다시 페이지를 표시하는데, 이때 안내 문구는 서버에서 오게 됩니다.
보통 비밀번호는 *로 표시하는데, 테스트할때는 그냥 문자열을 표시하는게 좋으므로 일단은 입력한 문자열이 보이게 했습니다.
다음포스팅에서는 숨기겠습니다.
아무 이상이 없이 회원가입이 완료되면 로그인창으로 이동합니다.
로그인하면 우측 상단의 버튼이 바뀝니다. My Profile을 눌러보겠습니다.
회원정보가 뜹니다. 비밀번호까지 보여주는 친절함!! 테스트 용이라서 그렇구요, 나중에는 숨겨야죠.
회원정보 수정을 해봅시다.
처음에는 현재의 정보가 표시됩니다.
이메일, 닉네임, 비밀번호를 바꿀 수 있습니다. 이메일과 닉네임을 바꾸어 보고, 비밀번호는 유지하는 것으로 해보겠습니다.
New Password는 옵션으로 입력하지 않으면 비밀번호가 바뀌지 않고, 입력하면 바뀌게 되어 있습니다.
제대로 바뀌었는지 확인할 수 있습니다.
다음 포스팅에서는 비밀번호 암호화를 하겠습니다!
github.com/imtaekh/my_app/tree/e7506f4b1773260ed4561f68f7204708aa8477af 에서 코드를 보실 수 있습니다. git clone한 다음 git reset --hard e7506f4하시면 컴퓨터에서 코드를 보실 수 있습니다. |
'javascript > w3schools nodejs' 카테고리의 다른 글
게시판 시작해봅시다 -6 (0) | 2017.02.23 |
---|---|
게시판 시작해봅시다 -5 (0) | 2017.02.23 |
게시판 시작해봅시다 -3 (0) | 2017.02.23 |
게시판 시작해봅시다 -2 (0) | 2017.02.23 |
게시판 시작해 봅시다 - 1 (0) | 2017.02.23 |