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
반응형