옹실이의 개발이야기

Node.js

(node.js/express.js)Login route 만들기

옹실 2021. 10. 23. 14:54

Login route 만들기

   1. DB에서 요청한 email 찾기(이메일 검증)
   2. DB에서 요청한 email이 있다면 비밀번호가 같은지 확인
   3. 비밀번호까지 같다면 토큰 생성 후 쿠키에 저장
   4. 확인

※ router(라우터) 란

route는 '길'이라는 뜻으로 네트워크 상에서 출발지에서 특정 목적지로 데이터를 보내는 경로.
route를 찾아내는 역할을 하는 장비를 router(라우터)라고 한다.

 


* 참고사항 *
진행방식 : User.js(User 스키마)에서 User 관련 function 만든 후 Index.js에서 호출
사용한 라이브러리/프로그램(서비스) : jsonwebtoken, cookie-parser, postman
DB : MongoDB(몽고DB)


 

1. 요청한 email를 DB에서 찾기(이메일 검증)

로그인 시 이메일을 입력하고 확인 버튼을 눌렀을때, 해당 이메일이 등록되어 있는지 아닌지 여부를
DB에서 확인함으로써 검증한다. 

- 메인(index.js)에서 post로 로그인 메소드 만든다

1
2
3
4
5
6
7
8
9
10
app.post('/login', (req, res) => {
  // user 모델 가져온 후 몽고DB의 findOne 메소드 이용
  User.findOne({ email: req.body.email }, (err, user) => {
    if(!user) { //user가 없다면 
      return res.json({
        loginSuccess: false,
        message: "제공된 이메일에 해당하는 유저가 없습니다."
      })
    }
})
cs


몽고 DB의 findOne 메소드를 이용해 user 스키마에 저장되어있는 data에
request로 받은 email(화면에서 입력한 email)이 있는지 찾는다.

 

2. 요청한 이메일이 DB에 있다면 비밀번호가 맞는지 확인한다(비밀번호 검증)

요청 email이 DB에 등록되어 있다면 비밀번호가 맞는지 검증한다.
비밀번호가 맞다면 해당 유저의 토큰을 생성해 쿠키에 저장해주고, 맞지 않다면 에러 처리해준다.

※ DB에 등록되어있는 비밀번호는 암호화되어있기 때문에 
   비밀번호 검증 시 request로 받은 비밀번호도 암호화 해 비교해야한다.
   (DB에서 이미 암호화한 것은 복호화 X) 

- User.js(user스키마)에서 comparePassword 메소드 만든다

1
2
3
4
5
6
7
8
userSchema.methods.comparePassword = function (plainPassword, cb){
    //comparePassword : 내가 만든 메소드 이름, cb : 콜백function 
    //plainPassword를 암호화해야함 (이미 암호화한 것은 복호화 X)
    bcrypt.compare(plainPassword, this.password, function (err, isMatch) { //this.password : user 스키마 (윗부분)에 있는 password 갖고온다 
        if(err) return cb(err); //비밀번호 같지 않다면 콜백으로 에러 리턴
        cb(null, isMatch) //비밀번호 같다면 에러 없이 boolean 값 return 
    }) 
}
cs

암호화 라이브러리 bcrypt 의 compare 메소드를 이용해 user 스키마에 있는 password(this.password) 와
req로 받아온 password(plainPassword)를 비교한다.
cb는 콜백function으로 비밀번호과 같지 않다면 에러를, 같다면 boolean값 (성공 시 true가 됨)을 리턴해준다.

 

- 메인(index.js) > User.findOne 메소드 안에서
  comparePassword 메소드를 호출한다.

1
2
3
4
    user.comparePassword( req.body.password , (err, isMatch) => { //비밀번호가 맞다면
      if(!isMatch)
      return res.json({ loginSuccess: false, message: "비밀번호가 맞지 않습니다."})
    })
cs

비밀번호가 맞지 않다면 에러처리, 맞다면 토큰을 생성해 쿠키에 저장해준다.

 

 

3. 비밀번호까지 같다면 토큰 생성 후 쿠키에 저장

비밀번호가 같을 경우 해당 user의 토큰을 생성 후 쿠키에 저장해준다.
토큰은 JSONWEBTOKEN 라이브러리, 쿠키는 쿠키 parser를 이용한다.

- jsonwebtoken 라이브러리를 설치한다.

visual studio code > 터미널에서 다음 명령어 입력하면 라이브러리가 설치된다.

1
npm install jsonwebtoken --save
cs



라이브러리 설치에 성공하면 터미널에 아래와 같은 정보가 나온다.




설치 후 아래 링크에서 사용법을 숙지해 활용한다.
https://www.npmjs.com/package/jsonwebtoken

 

jsonwebtoken

JSON Web Token implementation (symmetric and asymmetric)

www.npmjs.com

 

1
2
var jwt = require('jsonwebtoken');  
var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
cs

cf) 링크 타고 들어가서 확인해보면 (사용법) 
 jsonwebtoken을 import한 후 sign이라는 메소드를 이용해 토큰을 생성하는 것을 알 수 있다.

 

 

- User.js에서 토큰을 생성하는 메소드를 만든다

require메소드로 jsonwebtoken을 가져온 후 sign 메소드를 이용해 토큰을 생성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const jwt = require('jsonwebtoken');  //토큰 가져오기
 
userSchema.methods.generateToken = function(cb){
    var user = this//user 스키마 가져온다
 
    // jsonwebtoken을 이용해 token을 생성하기
    var token = jwt.sign(user._id.toHexString(), 'secretToken'); //DB에 _id라고 정의되어있는 부분
 
    //user스키마에 있는 token에 생성한 토큰 넣어준다
    user.token = token;    
    user.save(function(err, user){
        if(err) return cb(err) //에러가 있다면 콜백function으로 에러 리턴
        cb(null, user) //에러가 아니라면 에러 없이 유저 정보만 전달
    })
}
cs

유저 스키마에 있는 id(user._id)는 plain Text로 넣어야 하기 때문에 toHexString()을 사용해 sing 메소드에 넣는다.
여기서 secretToken은 내가 임의로 정한 단어로, user._id와 'secretToken'을 합쳐 token을 만든다. (토큰으로 user를 확인할 수 있다) 

user스키마에 있는 token에 새로 생성한 토큰을 넣고 저장, 에러처리 해준다.
에러가 아니라면 user에 토큰 정보를 담아 리턴한다.

 

 

 

에러가 아닐 경우 토큰 정보를 받아와서 쿠키에 저장해야하는데, 쿠키는 parser를 설치해주어야 한다.

- 쿠키 parser를 설치한다.

visual studio code > 터미널에서 다음 명령어를 입력하면 라이브러리가 설치된다.

1
npm install cookie-parser --save
cs



cookie-parser 설치에 성공하면 터미널에 아래와 같은 정보가 나온다.




 

- Index.js에서 generateToken 메소드 호출 후, 받아온 토큰을 쿠키에 저장한다

generateToken 메소드 호출 전에 ,
require 메소드로 쿠키 parser를 가져온 후, app에서 사용하기 위해 cookieparser를 use 메소드에 담아준다.

1
2
3
4
5
6
    // 쿠키 parser 가져온다
     const cookieParser = require('cookie-parser');
 
     app.use(cookieParser());
 
   
cs

 

User.js에서 만들었던 generateToken 메소드를 호출해 토큰을 받아온다.

1
2
3
4
5
6
7
8
 
      user.generateToken((err, user) => {  //에러가 아닐 경우 user에 토큰을 받아온다
        if(err) return res.status(400).send(err) //에러가 있다면 에러와 함께 status 400 리턴
 
        res.cookie("x_auth", user.token) // -> x_auth라는 이름으로 쿠키 생성됨
        .status(200//성공
        .json({ loginSuccess: true, userId: user._id})
      })
cs


오류 날 경우 status를 400('에러'를 의미), 에러를 리턴한다.
성공했을 경우 "x_auth"라는 이름(임의로 지정)에 토큰을 담아 쿠키를 생성하고
로그인 성공을 의미하는 loginSuccess: true, user의 id를 json 형태로 담아
status: 200('성공'을 의미) 과 함께 리턴한다.

 

 

4. 확인

- 서버 start

visual studio code > 터미널 > 명령어를 입력해 서버를 킨다.

1
npm run start
cs



몽고 DB 연결이 안되있을 경우 현재 사용중인 IP가 허용 되어있는지 확인한다.
(https://lowell-dev.tistory.com/36)

 

- POSTMAN에서 데이터를 request 해본다.

  postman > 로그인 > workspace > collections > + 클릭 > post로 http://localhost:5000/login 하나 만들어준다 > 
  Body > raw 선택(라디오버튼) > 
  {
    "email" : "test1@naver.com",
    "password" : "1234567"
  }
  입력 후 Send
  (여기서 입력하는 정보는 register 시 등록한 정보와 일치해야한다)

 

- 성공 여부 확인

성공했을 경우 POSTMAN에 하기와 같이 메시지가 뜬다.

'Node.js' 카테고리의 다른 글

Authentication 기능 만들기  (0) 2021.11.07
Node.js와 Express.js로 간단한 어플리케이션 만들기  (0) 2021.10.09