ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Node.js에서 로그인 기능 구현하기(+github 위키)
    BackEnd/Node.js 2021. 8. 28. 01:04

    안드로이드 스튜디오로 프론트 엔드, node.js로 백엔드를 해서 풀스택 토이프로젝트를 진행중이다. 지금 하고있는 토이 프로젝트에서 로그인 기능을 구현할때 사용한 코드에 대해 포스팅 하려 한다. 

     

    지금 하고 있는 토이프로젝트에서 로그인 기능은 클라이언트 쪽에서 request body에 email, pw를 보내면 서버 측에서 에러가 없을 경우 user의 idx, 토큰, 그리고 로그인 성공 메시지 및 status Code를 보내주는 형태이다. 

     


    - 로그인 라우터 전체 코드

    router.post('/signin', (req, res) => {
        const {
            email,
            pw
        } = req.body;
        const sql = `SELECT * FROM User WHERE email="${email}"`;
        connection.query(sql, function (err, rows, fields) {
            if (err) {
                console.log(err);
                return res.status(statusCode.NOT_FOUND).send(messageCode.REQUEST_FAIL);
            }
            else {
                if (rows.length === 0) {
                    return res.status(statusCode.MATCH_ERR).send(messageCode.INVALID_USER);
                }
                
                else if (pw !== rows[0].pw) {
                    return res.status(statusCode.MATCH_ERR).send(messageCode.INVALID_PW);
                } 
                else {
                    var token = jwt.sign({
                        email: email
                    }, process.env.JWT_SECRET);
    
                    return res.status(statusCode.SUCCESS).json({
                        code: statusCode.SUCCESS,
                        message: messageCode.SIGN_IN_SUCCESS,
                        userIdx : rows[0].id,
                        token: token
                    });                                    
                }
            }
            
        })
    })
    
    module.exports = router;

    하나씩 살펴보자.

    router.post('/signin', (req, res) => {
    ...
    }

    - 경로는 그냥 로그인이니까 간단하게 /signin이라고 줬다. 좀 더 기능이 세부적으로 많은 프로젝트들을 보면 user관련 작업은 /user/signin이런식으로 좀 더 세분화해서 경로를 주기도 하는듯 하다. 

    - post 메소드를 이용했다

     

    * get대신 post? 

    안드로이드 측에서 email과 pw로 이루어진 Body를 레트로핏 통신시 서버측에 보내려면 get방식의 http전송을 사용할 수 없다. get자체가 애초에 서버로부터 정보를 받아오는 느낌의 메소드라 그런 듯 하다. 로그인 기능의 경우 클라이언트 측에서 서버로 사용자의 email과 pw를 전달해주고 답을 받는 것이니 post를 사용하는 듯 하다. Postman으로 테스트 해볼땐 get / post 둘다 가능했는데 안드로이드 쪽에서 레트로핏 통신하다가 발견했다. 이런 이유로 대부분 로그인 메소드는 post를 사용하는 듯 하다.

     

    const sql = `SELECT * FROM User WHERE email="${email}"`;
        connection.query(sql, function (err, rows, fields) {
        	...
        }

    - sql문은 위처럼 SELECT *로 써 놨는데, 지금 다시 코드를 훑어보니 필요한 정보인 userIdx와 pw정도만 받아오는 쪽이 좀 더 깔끔할 것 같다.

    - 저 connection에 대해서 작성하자면, db쪽에 연결하는 부분은 모든 라우터에서 다 사용하니까 db와 연결하는 부분ㅇ르 따로 모듈화 해 두었다. 

     

    const mysql = require('mysql2');
    const config = require('../config/config.json');
    
    const connection = mysql.createConnection({
        host: config.development.host,
        user: config.development.username,
        database: config.development.database,
        password: config.development.password,
        multipleStatements: true,
    });
    
    moudle.exports = connection;

    * 지난번 포스팅에도 썼던것 같은데 config.json에 db키값등 유출되면 안되는 값들을 넣어놓았다면 git에 안올라가게 조심해야한다... (aws과금 우려...)

     

    쨌든 connection은 위처럼 모듈화해서 따로 파일에 빼 두었고, db와 연결해서 sql 쿼리를 보내면 db쪽에서 그 사용자에 대한 정보를 받을 수 있다.

    if (err) {
                console.log(err);
                return res.status(statusCode.NOT_FOUND).send(messageCode.REQUEST_FAIL);
            }
            else {
                if (rows.length === 0) {
                    return res.status(statusCode.MATCH_ERR).send(messageCode.INVALID_USER);
                }
                
                else if (pw !== rows[0].pw) {
                    return res.status(statusCode.MATCH_ERR).send(messageCode.INVALID_PW);
                } 
                else {
                    var token = jwt.sign({
                        email: email
                    }, process.env.JWT_SECRET);
    
                    return res.status(statusCode.SUCCESS).json({
                        code: statusCode.SUCCESS,
                        message: messageCode.SIGN_IN_SUCCESS,
                        userIdx : rows[0].id,
                        token: token
                    });                                    
                }
            }

    - if문은 db쪽 연결에서 문제가 있을 경우 걸리는 쪽이고 db연결 성공하면 else에 걸린다.

    - id가 없는 경우, id는 존재하지만 비밀번호가 틀린 경우에는 에러 메시지를 보내준다. 참고로 에러코드와 에러 메시지 들도 모듈화 해두었다. 좀 더 코드를 깔끔하게? 만들 수 있다.

    - 에러가 나지 않을 경우 토큰과 userIdx가 포함된 응답을 보내준다. 


    github에 작성한 서버 위키

    이런 식으로 클라이언트 측에 응답을 보내게끔 만들었다. 서버 쪽에는 이런 식으로 pm2로그가 찍힌다. (안드로이드쪽에서 로그인해서 통신 성공한 로그이다!)

    글 마무리를 어떻게 해야할지 모르겠네... 쨌든 아직 로그인밖에 안했지만 그래도 뭔가 풀스택으로 다 해봤다는게 뿌듯해서 기억이 날아가기 전에 포스팅했다. ㅎㅅㅎ

     

Designed by Tistory.