카테고리 없음 ·

node.js 웹사이트 만들기 글-2

728x90
반응형

 

오늘 쓴명령어

//mysql 접속명령어

mysql -u root -p

오늘 써본 sql 문
-- 'users' 테이블에 'role' 열 추가
ALTER TABLE users
ADD role VARCHAR(50);

-- 사용자에게 권한 할당
-- 예: 사용자 'john'을 관리자로 할당
UPDATE users
SET role = 'admin'
WHERE username = 'john';

-- 다른 사용자를 일반 사용자로 할당
UPDATE users
SET role = 'user'
WHERE username = 'jane';

-- . 이 쿼리는 'users' 테이블의 모든 회원 정보를 삭제합니다.

DELETE FROM users;


오늘 만든 사이트 기능

관리자 페이지 접속 제한 어드민권한만 접속가능 및 유저 접근 차단

유저 데시보드에 유저이름표시하은 코드 수정및 한글 꺠짐 방지 코드 넣음

오늘 서버 node.js 코드

const express = require('express');
const app = express();
const port = 3030;
const { MongoClient, ObjectId } = require('mongodb');
const mysql = require('mysql');
const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const crypto = require('crypto');

const secret = crypto.randomBytes(32).toString('hex');
console.log('안전한 secret 키:', secret);

app.use(session({
    secret: secret,
    resave: false,
    saveUninitialized: false,
}));
app.use(passport.initialize());
app.use(passport.session());

const winston = require('winston');
const bodyParser = require('body-parser');
require('dotenv').config();
// Winston 로그 설정
const logOptions = {
    level: 'info',
    format: winston.format.combine(
        winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
        winston.format.printf(({ timestamp, level, message }) => {
            return `${timestamp} [${level}] ${message}`;
        })
    ),
    transports: [
        new winston.transports.Console(), // 콘솔 출력
        new winston.transports.File({ filename: 'app.log' }) // 파일로 저장
    ]
};

const logger = winston.createLogger(logOptions);

// Console에 모든 로그 출력을 추가
console.log = (...args) => {
    logger.info(args.join(' '));
    // 원래 console.log를 유지하려면 아래 주석을 해제하세요.
    // originalConsoleLog(...args);
};

app.set('view engine', 'ejs');
app.use('/public', express.static('public/css'));
app.use('/yu', express.static('views/public/css'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use((req, res, next) => {
    const clientIp = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
    logger.info(`접속한 IP 주소: ${clientIp}`);
    next();
});
app.use((req, res, next) => {
    const logMessage = '사용자가 웹 사이트에 접속함 - IP 주소: ' +req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  
    // Winston 로그 작성
    logger.info(logMessage);
  
    // 클라이언트 IP 주소와 로그 메시지를 데이터베이스에 저장
    createAndStoreLog(logMessage, req.headers['x-forwarded-for'] || req.connection.remoteAddress);
  
    // 다음 미들웨어 또는 라우트 핸들러로 이동
    next();
  });
  
  
const url = process.env.MONGODB_URI;

let db;

(async () => {
    try {
        const client = await MongoClient.connect(url);
        logger.info('DB 연결 성공');
        db = client.db('forum');
        
        app.listen(port, () => {
            logger.info(`http://localhost:${port} 에서 서버 실행 중`);
        });
    } catch (err) {
        logger.error('DB 연결 실패', err);
    }
})();

const mysqldb = mysql.createConnection({
    host: process.env.MYSQL_HOST,
    user: process.env.MYSQL_USER,
    password: process.env.MYSQL_PASSWORD,
    database: process.env.MYSQL_DATABASE,
	charset: 'utf8mb4', // 이 부분을 추가하여 UTF-8로 설정
  });
  mysqldb.connect((err) => {
    if (err) {
      console.error('MySQL 연결 오류:', err);
      throw err;
    }
    console.log('MySQL 연결 성공');
  });
  
  // Express 설정
 
  
 // Periodically create and store logs function

// Periodically create and store logs function
function createAndStoreLog(message, clientIPAddress) {
    const logEntry = { message, ip_address: clientIPAddress };
  
    mysqldb.query('INSERT INTO logs SET ?', logEntry, (err) => {
      if (err) {
        console.error('Error storing log:', err);
      } else {
        console.log('Log stored successfully');
      }
    });
  }
  
  app.get('/', (req, res) => {

  if (req.session.user) {
    // 사용자가 로그인한 경우
     res.sendFile(__dirname + "/public/html/index.html");
    console.log('로그인 안한상태로 접속');
  } else {
	  res.sendFile(__dirname + "/public/html/index.html");
    console.log('로그인 안한상태로 접속');
  }
  })
app.get('/list', async (req, res) => {
    try {
        const result = await db.collection('post').find().toArray();
        logger.info('데이터베이스에서 목록을 성공적으로 가져옴');
        res.render('list.ejs', { 글목록: result });
    } catch (err) {
        logger.error('데이터베이스에서 목록을 가져오는 중 오류 발생', err);
        res.status(500).send('서버 오류');
    }
});
app.get('/write',(req,res) =>{
  res.render('write.ejs')
})
app.get('/write/error',(req,res) =>{
    res.render('error.ejs')
  })

  app.get('/server/error',(req,res) =>{
    res.render('server_error.ejs')
  })
app.post('/add',async (요청,응답) =>{
    try {
        if (요청.body.title == '') {
            return 응답.redirect('/write/error');
          } if (요청.body.title == ' ') {
            return 응답.redirect('/write/error');
          } else  {
            await db.collection('post').insertOne({ title : 요청.body.title, content : 요청.body.content })
            응답.redirect('/list') 
          }
     } catch (e) {
        console.log(e)
        응답.status(500).redirect('/server/error')
     } 
  
})

app.get('/detail/:id', async (요청, 응답) => {
    try {
        let result = await db.collection('post').findOne({ _id: new ObjectId(요청.params.id) });
        if (result === null) {
            return 응답.status(404).send('해당 글을 찾을 수 없습니다.');
        }
        응답.render('detail.ejs', { result: result });
    } catch (error) {
        console.error(error);
        응답.status(500).send('오류가 발생했습니다.');
    }
});
app.get('/shop', (req, res) => {
    // 여기에서 필요한 데이터를 가져와서 EJS 파일에 전달할 수 있습니다.
    const products = [
      { name: '상품1', price: 10000 },
      { name: '상품2', price: 20000 },
      { name: '상품3', price: 30000 }
    ];
  
    res.render('shop', { products }); // 'shop.ejs' 파일을 렌더링하고 products 데이터를 전달합니다.
  });
  
  
// 회원가입 페이지 렌더링
app.get('/join/membership', (req, res) => {
  // 회원가입 페이지 렌더링 (HTML 폼)
  res.sendFile(__dirname + '/public/html/u.html');
});

// 회원가입 POST 요청 처리
app.post('/join/membership', (req, res) => {
  // POST 요청으로부터 입력 데이터 추출
  const { email, phoneNumber, address, name, id, password } = req.body;

  // 빈 칸 검사
  if (!email || !phoneNumber || !address || !name || !id || !password) {
    return res.status(400).send('필수 입력 정보를 모두 제공해야 합니다.');
  }

  // 중복 정보 검사 (예: ID가 중복되지 않는지 확인)
  mysqldb.query('SELECT * FROM users WHERE id = ?', [id], (err, results) => {
    if (err) {
      console.error('중복 정보 검사 중 오류 발생:', err);
      return res.status(500).send('중복 정보 검사 중 오류 발생');
    }
    if (results.length > 0) {
      return res.status(400).send('이미 사용 중인 ID입니다.');
    }

    // 새 사용자 생성 및 데이터베이스에 저장
    const newUser = {
      email,
      phoneNumber,
      address,
      name,
      id,
      password,
      role: 'user', // 이 부분에서 일반 사용자 권한을 설정합니다.
    };

    mysqldb.query('INSERT INTO users SET ?', newUser, (err) => {
      if (err) {
        console.error('회원가입 중 오류 발생:', err);
        return res.status(500).send('회원가입 중 오류 발생');
      }

      // 가입 완료 페이지로 이동
      res.redirect('/Membership/registration/completed');
    });
  });
});


  


  // 가입 완료 페이지 라우트
  app.get('/Membership/registration/completed', (req, res) => {
    res.send('회원가입이 완료되었습니다.');
  });
// getLogsFromDatabase 함수 수정
// getLogsFromDatabase 함수 수정
function getLogsFromDatabase(db, callback) {
    db.query('SELECT * FROM logs', (err, results) => {
      if (err) {
        callback(err, null);
      } else {
        callback(null, results);
      }
    });
  }
  
  
  app.get('/logs', (req, res) => {
    // 데이터베이스에서 로그 목록을 가져오는 함수 호출 (db 객체를 전달)
    getLogsFromDatabase(mysqldb, (err, logs) => {
      if (err) {
        console.error('로그 목록을 가져오는 중 오류:', err);
        res.status(500).send('로그 목록을 가져오는 중 오류 발생');
      } else {
        res.render('logs.ejs', { logs }); // logs.ejs 템플릿을 렌더링하여 로그 목록 표시
      }
    });
  });
  app.get('/googleb1672fc63397d758', (req, res) => {
    res.sendFile(__dirname + "/public/html/googleb1672fc63397d758.html");
});
app.get('/robots.txt', (req, res) => {
    res.sendFile(__dirname + "/robots.txt");
});
// 로그인 페이지 렌더링
app.get('/login', (req, res) => {
  res.render('login.ejs');
});

app.post('/login', (req, res) => {
  const { id, password } = req.body;

  // 데이터베이스에서 사용자 확인
  mysqldb.query('SELECT * FROM users WHERE id = ? AND password = ?', [id, password], (err, results) => {
    if (err) {
      console.error('로그인 중 오류 발생:', err);
      return res.status(500).send('로그인 중 오류 발생');
    }

    if (results.length === 1) {
      const user = results[0]; // 로그인한 사용자 정보

      // 사용자 이름 가져오기
      const sqlGetName = 'SELECT name FROM users WHERE id = ?';
      mysqldb.query(sqlGetName, [id], (nameErr, nameResults) => {
        if (nameErr) {
          console.error('사용자 이름 가져오기 오류:', nameErr);
          return res.status(500).send('사용자 이름 가져오기 오류');
        }

        if (nameResults.length === 1) {
          const userName = nameResults[0].name;

          if (user.role === 'admin') {
            // 관리자 계정으로 로그인 성공
            req.session.user = user; // 세션에 사용자 정보 저장
            req.session.role = 'admin'; // 세션에 권한 저장
            req.session.userName = userName; // 사용자 이름을 세션에 저장
            console.log('관리자 계정 로그인 성공: ' + user.id);
            res.redirect('/admin-dashboard');
          } else if (user.role === 'user') {
            // 일반 사용자 계정으로 로그인 성공
            req.session.user = user; // 세션에 사용자 정보 저장
            req.session.role = 'user'; // 세션에 권한 저장
            req.session.userName = userName; // 사용자 이름을 세션에 저장
            console.log('일반 사용자 계정 로그인 성공: ' + user.id);
            res.redirect('/dashboard');
          } else {
            // 권한이 없는 경우
            console.log('로그인 실패: 권한이 없는 사용자입니다.');
            res.render('login.ejs', { error: '권한이 없는 사용자입니다.' });
          }
        } else {
          // 사용자 이름을 찾을 수 없음
          console.log('사용자 이름을 찾을 수 없습니다.');
          res.status(500).send('사용자 이름을 찾을 수 없습니다.');
        }
      });
    } else {
      // 아이디가 존재하지 않음
      console.log('로그인 실패: 아이디가 존재하지 않습니다.');
      res.render('login.ejs', { error: '아이디가 존재하지 않습니다.' });
    }
  });
});





app.get('/members', (req, res) => {
  const sql = 'SELECT id, password, role FROM users'; // 회원 정보 및 권한 정보가 있는 테이블명으로 수정해야 합니다.

  mysqldb.query(sql, (err, results) => {
    if (err) {
      console.error('회원 정보 가져오기 오류:', err);
      return res.status(500).send('오류 발생');
    }

    // EJS 템플릿 렌더링하여 회원 정보 및 권한 정보 표시
    res.render('members.ejs', { members: results });
  });
});

app.get('/admin-dashboard', (req, res) => {
  if (req.session.user && req.session.role === 'admin') {
    // 'admin' 권한이 있는 사용자만 액세스 가능
    res.render('admin-dashboard.ejs');
  } else {
    // 권한이 없는 경우 또는 로그인하지 않은 경우
    res.redirect('/login');
  }
});

app.get('/dashboard', (req, res) => {
  if (req.session.user && req.session.role === 'user') {
    // 'user' 권한이 있는 사용자만 액세스 가능
	  console.log(req.session.userName)
    res.render('dashboard.ejs', { userName: req.session.userName });
  } else {
    // 권한이 없는 경우 또는 로그인하지 않은 경우
    res.redirect('/login');
  }
});


app.use('/favicon.ico', express.static('public/favicon.ico'));
728x90
반응형