BE/Node.js

[Node.js] Node.js & Mysql 연동시키기 (完)

2sangmin 2022. 8. 12.

저번에 파일데이터베이스에 이어서 이번에는 진짜 Mysql에 연동시키기로 해보았다. 여태까지 진행했던 강의랑 내가하는 방식이 틀려서 따로 구글링하면서 찾아보다보니 시간이 좀 걸렸다.

우선 Mysql를 설치하고 테이블을 만들어주었다. (이과정은 생략하겠음)

이제 이걸 vscode에 config폴더를 만들고 db.js로 만들어서 불러와주자. 

 

 

db.js

const mysql = require("mysql");

const db = mysql.createConnection({
    host : 'localhost', // 데이터베이스 서버가 있는 주소
    user : 'root',
    password : '본인 비밀번호',
    database : 'login_lecture' // 사용할 데이터베이스 이름
});

db.connect();

module.exports =db;

 

나는 이 db.js를 다시 UserStorage.js에서 사용할것이므로, createConnection과 db.connect()만 해주었다.

일단 UserStorage.js에서 데이터베이스가 잘 불러와지나 console.log을 해보았는데 아니나 다를까 바로 에러가 떴다.

 

Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
    at Handshake.Sequence._packetToError (/dir/node_modules/mysql/lib/protocol/sequences/Sequence.js:47:14)
    at Handshake.ErrorPacket (dir/node_modules/mysql/lib/protocol/sequences/Handshake.js:123:18)
    at Protocol._parsePacket (dir/node_modules/mysql/lib/protocol/Protocol.js:291:23)
    at Parser._parsePacket (dir/node_modules/mysql/lib/protocol/Parser.js:433:10)
    at Parser.write (dir/node_modules/mysql/lib/protocol/Parser.js:43:10)
    at Protocol.write (dir/node_modules/mysql/lib/protocol/Protocol.js:38:16)
    at Socket.<anonymous> (dir/node_modules/mysql/lib/Connection.js:88:28)
    at Socket.<anonymous> (dir/node_modules/mysql/lib/Connection.js:526:10)
    at Socket.emit (events.js:315:20)
    at addChunk (internal/streams/readable.js:309:12)
    --------------------

 

이외에도 많지만 결국은 맨위 한줄만 구글링 해보니깐 , mysql 8.0버전이상의 오류라고 한다. 오류내용은

 

mysql 가 클라이언트 프로그램에서 mysql 패스워드 플러그인 "caching_sha2_password"을 소화하지 못해서 생기는 오류입니다.
클라이언트 프로그램에서 사용할 수 있도록 유저의 패스워드 Plugin을 바꿔줍시다.

라고 나온다.

 

해결방법은 mysql 을 켜서

 

mysql>  ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'mysql비밀번호';

 

라고 쳐주면된다. 그후에 확인을 하기위해서, 아래와 같이 쳐보면

 

mysql> SELECT Host,User,plugin,authentication_string FROM mysql.user;

root의 plugin이 caching_sha2_password에서 mysql_native_password로 바뀐것을 볼 수 있다.

이제다시 UserStorage.js로 돌아가보자.

 

UserStorage.js

"use strict";

const db = require("../config/db");

class UserStorage{
    static getUserInfo(id){
        return new Promise((resolve,reject)=>{
            const query= "SELECT * FROM users WHERE id = ?;";
            db.query(query,[id],(err,data)=>{
                if(err) reject(`${err}`);
                resolve(data[0]);
            })
        })
    }

    static async save(userInfo){
        return new Promise((resolve,reject)=>{
            const query= "INSERT INTO users(id, name, password) VALUES(?, ?, ?);";
            db.query(query,[userInfo.id, userInfo.name, userInfo.password],(err)=>{
                if(err) reject(`${err}`);
                resolve({ success: true});
            })
        })
    }
}

module.exports = UserStorage;

 

우선 const db = require("경로")를 통해 참조해주고, 원래의 로그인 기능을하던 getUserInfo와 save만 남겨놓고 다지웠다. 코드를 해석해보면, 기존의 파일데이터베이스는 readfile만해도 프로미스가 알아서 생성되었지만 이제는 수동으로 만들어준다. 그후에 db.query를 통해 아이디를 검색하게 해준다. data대신에 data[0]을 한 이유는 data를 하면 배열 형식으로 찍혀버리고만다. 직접 console.log를 통해 실험 해봤다.

 

왼쪽 data, 오른쪽 data[0]

 

getUserInfo와 Save의 차이는 성공했을경우 success:true를 반환하느냐 안하느냐의 차이가 있다. (회원가입 역할의 save가 success:true를 반환해주면 로그인창으로 넘어가기때문에 ) 그리고, 나머지는 sql문의 SELECT를 하거나 INSERT INTO를 하거나의 차이이므로, 잘 모르겠으면 sql 문법을 찾아보길 바란다.

이제 데이터베이스 연동은 끝이다. 중간에 위에서 말했던 에러 말고도 이상한 에러가 발생해서 3시간정도 고생하긴 했는데 생각보다 별거아닌 문제여서 열이 받았다. 그래도 결과적으로 잘 연결되었으니 기분은 좋다. 

 

 

결과화면(현재 데이터베이스 -> 회원가입 -> 데이터베이스 추가확인 -> 로그인 성공순이다)

현재 데이터베이스
(회원가입) 데이터베이스연동/성공/123456으로 만들었다.
데이터베이스에 잘 들어가있다.
금방 만든 아이디 비밀번호로 로그인하니깐 성공

db 연동하는과정에서 에러처리하느라 애먹어서 진이 빠졌다. 

오늘은 여기까지~~

댓글