티스토리 뷰
가장 기본이지만 필자에게는 제일 어려웠던 로그인 기능을 오늘 추가해보려고 한다.
전체적인 개념은 이해했지만 아직도 무언가 부족한 느낌이 들었지만, 오늘도 어느 정도 이해를 바탕으로 글을 쓰려고 한다.
1. 데이터 베이스에서 요청한 E-mail을 찾기
일단 회원가입이 되어있는지의 E-mail을 찾는 코드가 필요하다.
Express 라우트 메소드를 사용한다.
// POST method route
app.post('/', function (req, res) {
res.send('POST request to the homepage');
});
mongodb에서 제공하는 method를 이용한다.
//index.js
...
app.post('/login', (req, res) => {
User.findOne({ email: req.body.email }, (err, user) => {
if(!user) {
return res.json({
loginSuccess: false,
message: "제공된 이메일에 해당하는 유저가 없습니다."
})
}
})
})
...
만약 user이 참이 아닌 경우 res.json으로 리턴한다. 리턴할 때는 로그인은 실패하였고, 실패 메시지를 보낸다는 의미이다.
2. 요청된 이메일이 있을 때, 비밀번호가 맞는지 확인하기
// index.js
app.post('/login', (req, res) => {
...
user.comparePassword(req.body.password, (err, isMatch) => {
if(!isMatch)
return res.json({loginSuccess: false, message: "비밀번화 틀렸습니다."})
})
})
})
임의로 원하는 compoarePassword메소드를 생성하여, 맞지 않으면 비밀번호 오류 메시지를 클라이언트에 전송한다. 여기서 argument 두 개 중 하나는 req.body.password로 회원가입 시 입력한 비밀번호로 의미하며, callback function값으로 err값 혹은 비밀번호가 맞는지를 가져오게 된다.
3. userSchema.methods.compoarePassword를 생성
// moduls/User.js
...
userSchema.methods.comparePassword = function(plainPassword, cb) {
//plainPassword ex) 1234567 암호화된 비밀번호 ex)$2b$10$... 가 같은지 체크
bcrypt.compare(plainPassword, this.password, function(err, isMatch) {
if(err) return cb(err);
cb(null, isMatch)
})
}
...
여기에서 plainPassword는 일반적인 비밀번호이며, 현재 데이터베이스에 저장된 암호화된 비밀번호를 비교를 해야한다. 암호화된 비밀번호를 복호화를 할 수 없기에 plainPassword를 암호화하여 this.password(암호화된 비밀번호 = 데이터베이스에 저장된 비밀번호)를 비교한다.
4. 비밀번호가 동일하면 토큰을 생성하기
그전에 jsonwebtoken, cookie-parser라는 라이브러리를 설치한다.
yarn add jsonwebtoken cookie-parser
jsonwebtoken사이트를 참조하여 토큰을 생성한다.
// moduls/User.js
...
const jwt = require('jsonwebtoken');
userSchema.methods.generateToken = function(cb){
let user = this;
let token = jwt.sign(user._id.toHexString(), 'secretToken')
user.token = token;
user.save(function(err, user) {
if(err) return cb(err)
cb(null, user)
})
}
jwtwebtoken을 먼저 import를 해준 후 sign을 이용한다. 여기서 user._id와 secretToken값을 넣어야 token이 생성이 되기 때문에 두 가지의 값을 알아야 한다.
generateToken을 한 후 만약 에러가 있을 때, 에러메세지와 400 포트를 전달한다.
//index.js
...
const cookieParser = require('cookie-parser');
...
app.use(cookieParser());
...
app.post('/login', (req, res) => {
...
user.generateToken((err, user) => {
if(err) return res.status(400).send(err);
res.cookie("x_auth", user.token)
.status(200)
.json({loginSuccess: true, userId: user._id})
})
...
})
에러가 없는 경우, 토큰을 쿠키에 저장한다.
여기에서 x_auth는 관리자모드의 Application에서 Cookies에 x_auth가 하나 생성이 된다. 명칭은 자유롭게 바꿀 수 있는 듯하다.
여기에서는 쿠키와 로컬 스토리지에 대한 보완성이 더 좋은지에 대한 논란이 많아 일단 여기서는 쿠키로 저장하였다. 이렇게 하면 로그인 라우트를 모두 마친 것이다. 실제로 확인을 해보기 위해 postman을 연 후 라우터는 register에서 login으로 바꾼 후 확인을 한다.
아직 완벽한 이해가 부족하여 설명이 두리뭉실하거나 이해하는데 어려움이 있을 것이다. 오늘 공부한 내용은 깃허브에 올릴 것이며 참고하시길 바란다.
참고사이트
TMI
다시 공부하면서 새로 알게 된 내용을 적게 되었다. 이전에 body-parser도 express 미들웨어에 이미 있어 설치 없이 진행이 가능했다. 그리고 혹시나 궁금하여 cookie-parser을 찾아보니 이 또한 생략이 가능하게 express에 포함이 되어있었다.
그래서 위와 같이 진행을 한 후 다음과 같은 일부를 생략할 수 있다. 또한 cookie-parser 또한 설치를 하지 않아도 된다.
const cookieParser = require('cookie-parser');
app.use(cookieParser());
21. 03. 25 첫 업데이트
21. 05. 10 TMI 추가 설명 업로드
'Back-End > Node' 카테고리의 다른 글
boiler-plate : 로그아웃 기능을 만들기 (0) | 2021.03.27 |
---|---|
boiler-plate : Auth 기능만들기 공부과정 (0) | 2021.03.26 |
boiler-plate : 비밀번호를 암호화하여 받기 (0) | 2021.03.24 |
boiler-plate : 비밀 설정 정보 관리하는 방법 (0) | 2021.03.23 |
mongoDB : 몽고DB 연결하기 (0) | 2021.03.21 |
- Total
- Today
- Yesterday
- node-sass
- node.js
- 자바스크립트
- 파이썬
- 자바
- javascript
- 함수
- 배열
- 코딩테스트
- CSS
- 프로그래머스
- programmers
- array
- 리덕스
- 재공부
- Coding Test
- redux
- java
- 리액트 썸네일
- Git
- 뷰
- mongodb
- Visual Studio Code
- node
- 리액트 유튜브
- 노드
- Switch
- github
- react
- 리액트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |