본문 바로가기

Nodejs

tweet, auth DB연결 (2024-05-08)

(env, socket, orm, branch

더보기

환경 변수 관리
- 로컬에서 개발 또는 서버에 배포할 때 DB연결, 포트 설정, 시크릿 키 등 안전하게 관리하기 위한 환경 변수로 처리
- .env라는 파일에 환경 변수를 설정
    
    npm i dotenv


HTTP 통신
- 요청(request, 클라이언트)과 응답(response, 서버)으로 이루어짐
- 클라이언트가 요청을 먼저하고 서버는 수동적으로 응답해주는 구조(반이중통신 구조)

웹 소켓(Web Socket)
- 브라우저에서 지원하는 소켓통신
- 실시간 네트워킹이 보장된다
- 전이중통신 구조

웹 소켓의 동작 원리 
1. 최초 연결  요청 시 클라이언트에서 HTTP를 통해 웹서버에 요청한다
=> 핸드쉐이크 Handshake: HTTP통신을 Websoket 프로토콜로 전환 시킨다
2. 연결이 수립되면 클라이언트와 서버 양측간의 데이터를 통신 단계가 시작
    - 양방향 통신(전이중통신)
    - 상대방에서 ping 패킷을 보낼 수 있음
3. 클라이언트 홋은 서버 양측 누구나 연결을 종료할 수 있음

Socket.IO
- Node.js 기반의 웹소켓 라이브러리
- 실시간 양방향 통신을 가능하게 해주는 도구

    npm i socket.io

 

ORM(객체 관계 매핑, Object Relational Mapping)
- 객체 지향 프로그래밍 언어에서 사용되는 객체와 관계형 데이터베이스 간의 불일치를 해결하기 위한 기술
- 객체 모델과 관계형 데이터 베이스의 테이블 간의 매핑을 수행하여 개발자가 SQL 쿼리 대신 객체 지향 코드를 사용할 수 있도록 함


ODM(객체 문서 매핑, Object Document Mapping)
- NoSQL 데이터 베이스와 객체 지향 프로그래밍 언어 간의 매핑을 제공하는 기술
- 주로 문서 지향 데이터베이스(MongoDB)와 함께 사용

현재 작업중인 브랜치를 확인
- 목록을환인
    git branch
    - * 표사기 되어 있는 것이 현재 작업중인 브랜치

- branch 생성하기
git branch 브랜치 이름

- branch 전환하기
git switch 브랜치이름
git checkout 브랜치이름

- branch 생성과 도싱에 전환하기
git branch -b 브랜치이름

 

 

<code>

 

controller > auth.js

더보기

 

import * as authRepository from '../data/auth.js';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import { config } from '../config.js';


function createJwtToken(id){
    return jwt.sign({id}, config.jwt.secretKey, {expiresIn: config.jwt.expiresInSec});
};

export async function signup(req, res, next){
    const {username, password, name, email, url} = req.body;
    const found = await authRepository.findByUsername(username);
    if(found){
        return res.status(409).json({message:`${username}이 이미 있습니다`});
    }
    const hashed = await bcrypt.hash(password, config.bcrypt.saltRounds);
    const userId = await authRepository.createUser({username, hashed, name, email, url});
    const token = createJwtToken(userId);
    res.status(201).json({token, username});
};

export async function login(req, res, next){
    const {username, password} = req.body;
    const user = await authRepository.findByUsername(username);
    if(!user){
        return res.status(401).json({message : '아이디를 찾을 수 없음'})
    }
    
    const isValidpassword = await bcrypt.compareSync(password, user.password);
    if(!isValidpassword){
        return res.status(401).json({message : `비밀번호가 틀렸음`});
    }
    const token = createJwtToken(user.id);
        return res.status(200).json({token, username});
};

export async function me(req, res, next){
const user = await authRepository.findById(req.userId);
if(!user){
    return res.status(404).json({message : '일치하는 사용자가 없음'})
}
res.status(200).json({token : req.token, username: user.username})
}

// export async function verify(req, res, next){
//     const token = req.header['Token'];
//     if(token){
//         res.status(200).json(token);
//     }
// };

 

data > auth.js

더보기
import { db } from '../db/database.js';

// 아이디(username) 중복검사
export async function findByUsername(username){
    return db.execute('select * from users where username = ?', [username]).then((result) => {
         console.log(result);
         console.log(result[0][1]);
        return result[0][0];
    });
}
// id 중복검사
export async function findById(id){
    return db.execute('select * from users where id = ?', [id]).then((result) => result[0][0]);
}

export async function createUser(user){
    const {username, hashed, name, email, url} = user;
    return db.execute('insert into users (username, password, name, email, url) values (?, ?, ?, ?, ?)', [username, hashed, name, email, url]).then((result) =>{console.log(result); 
    return result[0].insertId
});
};

export async function login(username){
    return db.execute('select username, password from users where username = ?',[username]).then((result) => {console.log(result);
        return result;
    
    });
};

 

 

controller > tweet.js

더보기
import * as tweetRepository from '../data/tweet.js';
// 여러 트윗을 가져오는 함수
export async function getTweets(req, res){
    const username = req.query.username;
    const data = await (username ? tweetRepository.getAllByUsername(username)
                                 : tweetRepository.getAll());
    res.status(200).json(data);
}
// 하나의 트윗을 가져오는 함수
export async function getTweet(req, res, next) {
    const id = req.params.id;
    const tweet = await tweetRepository.getById(id);
    if(tweet){
        res.status(200).json(tweet);
    }else{
        res.status(404).json({message: `${id}의 트윗이 없습니다`})
    }
}
// 트윗을 생성하는 함수
export async function createTweet(req, res, next) {
    const { text } = req.body;
    const tweet = await tweetRepository.create(text, req.userId);
    res.status(201).json(tweet);
}
// 트윗을 변경하는 함수
export async function updateTweet(req, res, next) {
    const id = req.params.id;
    const text = req.body.text;
    const tweet = await tweetRepository.update(id, text);
    if(tweet){
        res.status(201).json(tweet);
    }else{
        res.status(404).json({message: `${id}의 트윗이 없습니다`})
    }
}
// 트윗을 삭제하는 함수
export async function deleteTweet(req, res, next) {
    const id = req.params.id;
    await tweetRepository.remove(id);
    res.sendStatus(204);
}

 

data > tweet.js

더보기
import { db } from '../db/database.js';
const SELECT_JOIN = 'select tw.id, tw.text, tw.createdAt, tw.userId, us.username, us.name, us.email, us.url from tweets as tw join users as us on tw.userId = us.id';
const ORDER_DESC = 'order by tw.createdAt desc';

// 모든 트윗을 리턴
export async function getAll() {
    return db.execute(`${SELECT_JOIN} ${ORDER_DESC}`).then((result) => {
        console.log(result);
        return result;
    });
}
// 해당 아이디에 대한 트윗을 리턴
export async function getAllByUsername(username){
    return db.execute(`${SELECT_JOIN} where username = ? ${ORDER_DESC}`, [username]).then((result) => {
        console.log(result);
        return result;
    });
}
// 글번호에 대한 트윗을 리턴
export async function getById(id){
    return db.execute(`${SELECT_JOIN} where tw.id = ? ${ORDER_DESC}`, [id]).then((result) => {
        console.log(result);
        return result;
    });
}
// 트윗을 작성
export async function create(text, userId){
    return db.execute('insert into tweets (text, userId) values (?, ?)', [text, userId]).then((result) => {
        console.log(result);
        return getById(result[0].insertId);
    });
}
// 트윗을 변경
export async function update(id, text){
    return db.execute('update tweets set text = ? where id = ?', [text, id]).then((result) => {
        console.log(result);
        return getById(id);
    });
}
// 트윗을 삭제
export async function remove(id){
    return db.execute('delete from tweets where id = ?', [id]);
}

 

database.js

더보기
import mysql from 'mysql2';
import { config } from '../config.js';

const pool = mysql.createPool({
    host : config.db.host,
    port : config.db.port,
    user : config.db.user,
    database : config.db.database,
    password : config.db.password
});

export const db = pool.promise();

 

 

 

'Nodejs' 카테고리의 다른 글

Mongoose (2024-05-10)  (0) 2024.05.10
MongoDB (2024-05-09)  (0) 2024.05.10
Authentication (2024-05-02)  (0) 2024.05.02
과제 회원가입, 로그인 router, tweet 활용  (0) 2024.04.29
리팩토링, validation(2024-04-29)  (0) 2024.04.29