본문 바로가기
Web - 백엔드/Node.js

[Node.js] Passport 모듈을 이용한 로그인 구현 2 - 로그인 구현

by 미래문 2019. 1. 29.
반응형


 

 

이전 포스트 보러가기

 

[Node.js] Passport 모듈을 이용한 로그인 구현 1 - 모듈 설치 / 준비

Node.js 모듈 중에는 Passport라는 모듈이 있습니다. 이 모듈을 사용하면 로그인 시에 인증을 보다 쉽게 구현할 수 있습니다. 프로젝트를 다음과 같이 구성합니다. 코드를 다음과 같이 입력합니다. /m

futuregate.tistory.com

 

이전 과정을 모르시는 분들은 위 링크로 가셔서 보고 오시길 바랍니다~

passport모듈을 사용할 준비가 되었으니, 이제 사용자를 생성하고, 로그인(인증)까지 구현해 보도록 하겠습니다.

먼저 /api/routes/users.js 입니다.

/api/routes/users.js

var express = require('express');
var router = express.Router();
const bcrypt = require('bcryptjs');
const User = require('../../models/User');
router.get('/', (req, res) =>
{
    res.send("패스포트 모듈 테스트");
});
router.post('/register', (req, res) =>
{
    User.findOne(
    {
        email: req.body.email
    }).then(user =>
    {
        if (user)
        {
            return res.status(400).json(
            {
                email: "해당 이메일을 가진 사용자가 존재합니다."
            })
        }
        else
        {
            const newUser = new User(
            {
                email: req.body.email,
                name: req.body.name,
                password: req.body.password
            });
            bcrypt.genSalt(10, (err, salt) =>
            {
                bcrypt.hash(newUser.password, salt, (err, hash) =>
                {
                    if (err) throw err;
                    newUser.password = hash;
                    newUser.save().then(user => res.json(user)).catch(err => console
                        .log(err));
                })
            })
        }
    })
}) module.exports = router;

전에 있던 라우터 파일에 bcryptjs 모듈과 사용자 모델을 가져옵니다. post방식으로 사용자 정보를 넘겨주면, 이메일을 기준으로 해당 이메일을 가진사람이 있는지 체크합니다. 만약 있다면 오류라는 뜻을 가진
400 신호를 클라이언트에 전송하고, json 형태로 해당 사용자가 있음을 출력해줍니다.

중복되는 사용자가 없다면 회원가입을 진행합니다. 그러나, 보통 비밀번호는 암호화가 되어있어야 합니다.
이전 포스트에서 언급했듯이 bcryptjs 모듈은 해쉬코드로 암호화를 쉽게 해주는 역할을 합니다.

따라서, 위의 코드로 newUser 객체에 받았던 비밀번호를 가지고서 salt(랜덤 시드) 값에 의해 해쉬코드로 인코딩을 진행합니다. 완료되었다면, newUser의 password에 변환된 해쉬코드값 hash를 덮어씌우고,
사용자 데이터를 저장합니다.

한번 포스트맨을 통해 잘 동작하는지 테스트 해보겠습니다.

 

위와 같이 POST방식으로 전송 메서드를 선택하고, 주소를 localhost:5000/api/users/register로 잡습니다. 앞에 /api/users/가 붙는 이유는 server.js에서 라우터를 설정할 때 경로를 /api/users로 주었기 때문입니다. 변경하시고 싶으신 분들은 server.js에서 변경하셔도 무방합니다.

다음으로 body를 선택하고, x-www-form=urlencoded를 선택한 뒤, 위와 같이 email, password, name값을 작성해줍니다. 모두 required로 설정되어 있기 때문에 한개라도 빠뜨리면 오류가 납니다.

그 후, send를 눌러서 회원가입이 잘 되었는지 확인합니다.

 

설정한 대로 email과 name값이 잘 넘겨졌고, password또한 암호화되어 저장되었음을 확인 할 수 있습니다.

계속해서 /routes/api/users.js 에 로그인을 추가하도록 하겠습니다.

/routes/api/users.js

상단 모듈 로드 부분에 다음 코드를 추가합니다.

const jwt = require('jsonwebtoken');
const keys = require('../../config/keys');

그 다음, 위에서 만들었던 /register 라우터 밑에 새로운 라우터 코드를 추가합니다.

router.post('/login', (req, res) =>
{
    const email = req.body.email;
    const password = req.body.password;
    // email로 회원 찾기
    User.findOne(
    {
        email
    }).then(user =>
    {
        if (!user)
        {
            errors.email = "해당하는 회원이 존재하지 않습니다.";
            return res.status(400).json(errors);
        }
        // 패스워드 확인           
        bcrypt.compare(password, user.password)
            .then(isMatch =>
            {
                if (isMatch)
                {
                    // 회원 비밀번호가 일치할 때                         
                    // JWT PAYLOAD 생성                        
                    const payload = {
                        id: user.id,
                        name: user.name
                    };

                    // JWT 토큰 생성                         
                    // 1시간 동안 유효                         
                    jwt.sign(payload, keys.secretOrKey,
                    {
                        expiresIn: 3600
                    }, (err, token) =>
                    {
                        res.json(
                        {
                            success: true,
                            token: 'Bearer ' + token
                        })
                    });
                }
                else
                {
                    errors.password = "패스워드가 일치하지 않습니다.";
                    return res.status(400).json(errors);
                }
            });
    })
});

login에서는 email과 password를 받아서, 먼저 해당하는 회원이 있는지( 회원가입이 되어 있는지) 체크합니다. 만약 존재하는 회원이라면, bcryptjs 모듈을 이용하여 입력받은 password를 암호화했을때, 가입 할 때 저장시킨 password와 일치하는지 검사하여, 맞다면 jwt을 생성합니다.

jwt에는 payload값으로 사용자의 이름과 아이디가 들어갑니다. 한번 생성된 jwt의 유효시간은 expiresIn으로 결정되며, 초단위입니다. 현재는 3600초로 1시간 동안 유효하도록 설정하였습니다.

로그인에 성공했다면 클라이언트에는 json형태로 jwt토큰 값이 출력되어 나올 것입니다.

그렇다면 포스트맨으로 다시 확인해 볼까요? 앞서 위에서 만들었던 아이디 test@test.com과 비밀번호 test1234로 테스트 해보겠습니다.

 

POST방식으로 로그인에 필요한 인자들을 넘겨준 결과, 아래와 같이 jwt 값이 출력되어 나오는 것을 볼 수 있습니다.

다음 포스트에서는 현재 로그인된 회원의 정보를 출력해보도록 하겠습니다.

반응형

댓글