node.js웹사이트 만들기

node.js 백엔드 구축 3강

프린_ 2023. 10. 24. 10:21
728x90
const express = require('express');
const app = express();
const port = 3030;
const nodemailer = require('nodemailer');
const mysql = require('mysql');
const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const crypto = require('crypto');
const moment = require('moment-timezone');
const winston = require('winston');
const bodyParser = require('body-parser');
const SitemapGenerator = require('sitemap-generator');
const multer = require('multer');
require('dotenv').config();
const bcrypt = require('bcrypt');
const path = require('path');
const fs = require('fs');
const http = require('http');
const socketIo = require('socket.io');

// MySQL 연결 설정
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: 'utf8'
});

mysqldb.connect((err) => {
    if (err) {
        console.error('MySQL 연결 오류:', err);
        throw err;
    }
    console.log('MySQL 연결 성공');
});

// 로그 설정
const logOptions = {
    level: 'info',
    format: winston.format.combine(
        winston.format.timestamp(),
        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.log = (...args) => {
    logger.info(args.join(' '));
};

// Express 설정
app.use(session({
    secret: crypto.randomBytes(32).toString('hex'),
    resave: false,
    saveUninitialized: false,
}));

app.use(passport.initialize());
app.use(passport.session());
const server = http.createServer(app);
const io = socketIo(server);
const wss = new WebSocket.Server({ server });
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;
    const logMessage = `사용자가 웹 사이트에 접속함 - IP 주소: ${clientIp}`;
    logger.info(logMessage);
    createAndStoreLog(logMessage, clientIp);
    next();
});


function createAndStoreLog(message, clientIPAddress) {
    const currentTime = moment().tz('Asia/Seoul').format('YYYY-MM-DD HH:mm:ss');
    const logEntry = { timestamp: currentTime, message: message, ip_address: clientIPAddress };
    mysqldb.query('INSERT INTO logs SET ?', logEntry, (err, results) => {
        if (err) {
            console.error('로그 저장 중 오류 발생:', err);
        } else {
            console.log('로그가 성공적으로 저장되었습니다.');
        }
    });
}

const generator = SitemapGenerator('https://fg-uonqq.run.goorm.site', {
    stripQuerystring: false, // 쿼리 문자열을 포함할지 여부
});

generator.on('done', () => {
    console.log('사이트 맵 생성이 완료되었습니다.');
});

const generateSitemapInterval = 24 * 60 * 60 * 1000; // 24시간(하루)마다

const generateSitemap = () => {
    generator.start();
};

setInterval(generateSitemap, generateSitemapInterval);

app.get('/sitemap.xml', (req, res) => {
    res.sendFile(__dirname + '/sitemap.xml');
});

app.get('/', (req, res) => {
    if (req.session.user) {
        if (req.session.role === 'admin') {
            
			res.render('index_a.ejs');
            console.log('관리자 계정으로 로그인 후 홈');
        } else {
            res.render('index_u.ejs');
            console.log('일반 사용자 계정으로 홈에 접속');
        }
    } else {
        res.render('index.ejs');
        console.log('로그인 안한 상태로 접속');
    }
});

app.get('/server/error', (req, res) => {
    res.render('server_error.ejs');
});

app.get('/shop', (req, res) => {
    const products = [
        { name: '상품1', price: 10000 },
        { name: '상품2', price: 20000 },
        { name: '상품3', price: 30000 }
    ];

    res.render('shop', { products });
});

// 회원가입 페이지 렌더링
app.get('/join/membership', (req, res) => {
    res.sendFile(__dirname + '/public/html/u.html');
});
app.get('/r', (req, res) => {
    res.sendFile(__dirname + '/public/html/r.txt');
});


// 회원가입 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입니다.');
        }

        // 암호 해시 생성
        bcrypt.hash(password, 10, (err, hash) => {
            if (err) {
                console.error('암호 해시 생성 중 오류 발생:', err);
                return res.status(500).send('암호 해시 생성 중 오류 발생');
            }

            // 새 사용자 생성 및 데이터베이스에 저장
            const newUser = {
                email,
                phoneNumber,
                address,
                name,
                id,
                password: hash,
                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 함수 수정
function getLogsFromDatabase(db, callback) {
    db.query('SELECT * FROM logs', (err, results) => {
        if (err) {
            callback(err, null);
        } else {
            callback(null, results);
        }
    });
}

// '/logs' 경로에 대한 라우트 핸들러
app.get('/logs', (req, res) => {
    if (req.session.user && req.session.role === 'admin') {
        // 'admin' 권한이 있는 사용자만 액세스 가능

        // 여기에서 데이터베이스에서 로그 목록을 가져오는 코드를 추가
        mysqldb.query('SELECT * FROM logs', (err, results) => {
            if (err) {
                console.error('로그 목록을 가져오는 중 오류:', err);
                res.status(500).send('로그 목록을 가져오는 중 오류 발생');
            } else {
                const logs = results; // 로그 데이터를 변수에 저장

                // 로그 데이터를 'logs.ejs' 페이지에 전달
                res.render('logs.ejs', { logs });
            }
        });
    } else {
        // 'admin' 권한이 아닌 경우 접근 불가능
        res.status(403).send('접근이 거부되었습니다.');
    }
});

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 = ?', [id], (err, results) => {
        if (err) {
            console.error('로그인 중 오류 발생:', err);
            return res.status(500).send('로그인 중 오류 발생');
        }

        if (results.length === 1) {
            const user = results[0];

            // 비밀번호 비교
            bcrypt.compare(password, user.password, (bcryptErr, result) => {
                if (bcryptErr) {
                    console.error('비밀번호 확인 중 오류 발생:', bcryptErr);
                    return res.status(500).send('비밀번호 확인 중 오류 발생');
                }

                if (result) {
                    // 비밀번호가 일치하는 경우, 로그인 성공
                    // 사용자 이름 가져오기
                    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('/');
                            } else if (user.role === 'user') {
                                // 일반 사용자 계정으로 로그인 성공
                                req.session.user = user; // 세션에 사용자 정보 저장
                                req.session.role = 'user'; // 세션에 권한 저장
                                req.session.userName = userName; // 사용자 이름을 세션에 저장
                                console.log('일반 사용자 계정 로그인 성공: ' + user.id);
                                res.redirect('/');
                            } else {
                                // 권한이 없는 경우
                                console.log('로그인 실패: 권한이 없는 사용자입니다.');
                                res.render('login.ejs', { error: '권한이 없는 사용자입니다.' });
                            }
                        } else {
                            // 사용자 이름을 찾을 수 없음
                            console.log('사용자 이름을 찾을 수 없습니다.');
                            res.status(500).send('사용자 이름을 찾을 수 없습니다.');
                        }
                    });
                } else {
                    // 비밀번호가 일치하지 않는 경우, 로그인 실패
                    console.log('로그인 실패: 비밀번호가 일치하지 않습니다.');
                    res.render('login.ejs', { error: '비밀번호가 일치하지 않습니다.' });
                }
            });
        } else {
            // 아이디가 존재하지 않음
            console.log('로그인 실패: 아이디가 존재하지 않습니다.');
            res.render('login.ejs', { error: '아이디가 존재하지 않습니다.' });
        }
    });
});

app.get('/m', (req, res) => {
    // 권한 확인: 사용자의 권한이 'admin'인 경우에만 액세스 허용
    if (req.session.user && req.session.role === 'admin') {
        const sql = 'SELECT id, email, phoneNumber, address, name, 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 });
        });
    } else {
        // 'admin' 권한이 아닌 경우 접근 거부
        res.status(403).send('액세스가 거부되었습니다.');
    }
});
app.delete('/deleteMember/:id', (req, res) => {
  const memberId = parseInt(req.params.id);

  // 여기에서 데이터베이스 쿼리를 사용하여 사용자를 삭제하도록 수정해야 합니다.
  const sql = 'DELETE FROM users WHERE id = ?';

  mysqldb.query(sql, [memberId], (err, results) => {
    if (err) {
      console.error('사용자 삭제 오류:', err);
      return res.json({ success: false });
    }

    return res.json({ success: true });
  });
});

app.get('/admin-dashboard', (req, res) => {
    if (req.session.user && req.session.role === 'admin') {
        // 'admin' 권한이 있는 사용자만 액세스 가능
        res.render('admin-dashboard.ejs', { userName: req.session.userName });
    } 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'));

app.get('/detail/:id', (req, res) => {
    const postId = req.params.id;
    const currentUser = req.session.user; // 현재 로그인한 사용자 정보

    // 글 조회 쿼리를 수행 (post 테이블에서 가져오도록 수정)
    mysqldb.query('SELECT * FROM post WHERE id = ?', [postId], (err, results) => {
        if (err) {
            console.error('데이터베이스에서 글 조회 중 오류:', err);
            return res.status(500).send('오류가 발생했습니다.');
        }

        if (results.length === 0) {
            return res.status(404).send('해당 글을 찾을 수 없습니다.');
        }

        // 글을 조회한 결과를 가져오고 현재 사용자와 글 작성자를 비교
        const post = results[0];

        // 사용자 역할을 확인하여 관리자인 경우 항상 삭제할 수 있도록 설정
        // 또는 글 작성자와 현재 사용자가 동일한 경우에만 삭제할 수 있도록 설정
        let canDelete = false;

        if (currentUser) {
            // 현재 사용자가 로그인한 경우에만
            if (currentUser.id === post.user_id || currentUser.role === 'admin') {
                canDelete = true;
            }
        }

        // 파일 URL을 파일 이름을 사용하여 생성
        const filePath = `/f/${post.file_path}`;

        // 파일 유형에 따라 이미지와 비디오를 구별
        const isImage = filePath.match(/\.(jpg|jpeg|png|gif)$/i);
        const isVideo = filePath.match(/\.(mp4|avi|mkv)$/i);

        res.render('detail.ejs', { post, canDelete, filePath, isImage, isVideo });
    });
});

app.post('/delete/:id', (req, res) => {
    const postId = req.params.id;

    if (req.session.user) {
        // 글 삭제 권한 확인: 관리자 또는 글 작성자만 삭제할 수 있음
        if (req.session.user.role === 'admin') {
            // 관리자 권한을 가진 사용자는 언제나 글을 삭제할 수 있음
            mysqldb.query('DELETE FROM post WHERE id = ?', [postId], (err) => {
                if (err) {
                    console.error('글 삭제 중 오류:', err);
                    return res.status(500).send('글 삭제 중 오류 발생');
                }

                console.log(`글(ID: ${postId})이 삭제되었습니다.`);
                res.redirect('/');
            });
        } else {
            // 글 작성자 확인: 로그인한 사용자와 글 작성자가 동일한지 확인
            mysqldb.query('SELECT user_id FROM post WHERE id = ?', [postId], (userErr, userResults) => {
                if (userErr) {
                    console.error('글 작성자 확인 중 오류 발생:', userErr);
                    return res.status(500).send('글 작성자 확인 중 오류 발생');
                }

                if (userResults && userResults.length > 0) {
                    const postUserId = userResults[0].user_id;
                    if (postUserId === req.session.user.id) {
                        // 글 작성자와 로그인한 사용자가 동일한 경우 글을 삭제할 수 있음
                        mysqldb.query('DELETE FROM post WHERE id = ?', [postId], (deleteErr) => {
                            if (deleteErr) {
                                console.error('글 삭제 중 오류:', deleteErr);
                                return res.status(500).send('글 삭제 중 오류 발생');
                            }

                            console.log(`글(ID: ${postId})이 삭제되었습니다.`);
                            res.redirect('/');
                        });
                    } else {
                        // 글 작성자와 로그인한 사용자가 동일하지 않은 경우 접근 거부
                        console.log('글 삭제 권한 없음: 글 작성자와 로그인한 사용자가 다름');
                        res.status(403).send('글 삭제 권한이 없습니다.');
                    }
                } else {
                    // 글 작성자를 찾을 수 없음
                    console.error('글 작성자를 찾을 수 없음.');
                    res.status(500).send('글 작성자를 찾을 수 없음');
                }
            });
        }
    } else {
        // 로그인하지 않은 경우 글 삭제 권한이 없음
        console.log('글 삭제 권한 없음: 로그인하지 않음');
        res.status(403).send('글 삭제 권한이 없습니다.');
    }
});

// 게시글 작성 페이지 렌더링
app.get('/write', (req, res) => {
    res.render('write.ejs');
});
app.get('/1', (req, res) => {
    res.render('1.ejs');
});


app.get('/yt', (req, res) => {
    res.render('yt.ejs');
});

// 로그아웃
app.get('/logout', (req, res) => {
    req.session.destroy((err) => {
        if (err) {
            console.error('로그아웃 중 오류 발생:', err);
            return res.status(500).send('로그아웃 중 오류 발생');
        }
        res.redirect('/');
    });
});
app.get('/list', (req, res) => {
    // 데이터베이스에서 "post" 테이블의 글 목록을 가져오는 쿼리
    mysqldb.query('SELECT id, title, content FROM post', (err, results) => {
        if (err) {
            console.error('데이터베이스에서 글 목록을 가져오는 중 오류 발생:', err);
            return res.status(500).send('서버 오류');
        }

        // 글 목록을 EJS 템플릿으로 렌더링하여 클라이언트에 전달
        res.render('list.ejs', { 글목록: results });
    });
});
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/'); // 파일 저장 경로 (uploads 디렉토리에 저장)
  },
  filename: (req, file, cb) => {
    const extname = path.extname(file.originalname);
    cb(null, Date.now() + extname); // 파일 이름을 고유하게 설정
  },
});

const upload = multer({ storage });

app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

app.post('/write', upload.single('file'), (req, res) => {
    // 로그인하지 않은 경우 글 작성 권한이 없음
    if (!req.session.user) {
        console.log('글 작성 권한 없음: 로그인하지 않음');
        return res.status(403).send('글 작성 권한이 없습니다.');
    }

    // POST 요청으로부터 입력 데이터 추출
    const { title, content } = req.body;
    const user_id = req.session.user.id;

    // 빈 칸 검사
    if (!title || !content) {
        console.log('필수 정보를 모두 입력해야 함');
        return res.status(400).send('필수 정보를 모두 입력해야 합니다.');
    }

    // 파일을 서버에 저장하고 제목과 내용을 데이터베이스에 저장
    savePostToDatabase(req, title, content, user_id, req.file)
        .then((result) => {
            console.log('새로운 글(ID: ' + result.insertId + ')이 작성되었습니다.');
            res.redirect('/');
        })
        .catch((err) => {
            console.error('글 작성 중 오류 발생:', err);
            return res.status(500).send('글 작성 중 오류 발생');
        });
});

// 데이터베이스에 제목, 내용 및 파일 저장하는 함수
function savePostToDatabase(req, title, content, user_id, file) {
    return new Promise((resolve, reject) => {
        const query = 'INSERT INTO post (title, content, user_id, file_path) VALUES (?, ?, ?, ?)';
        const filePath = file ? 'uploads/' + file.filename : null;
        mysqldb.query(query, [title, content, user_id, filePath], (err, result) => {
            if (err) {
                reject(err);
            } else {
                resolve(result); // 새로 생성된 게시물 정보 반환
            }
        });
    });
}

app.get('/f/uploads/:filename', (req, res) => {
    const fileName = req.params.filename;
    const filePath = path.join(__dirname, 'uploads', fileName);

    // 파일 확장자에 따라 Content-Type 설정
    if (fileName.endsWith('.jpg') || fileName.endsWith('.jpeg')) {
        res.setHeader('Content-Type', 'image/jpeg');
    } else if (fileName.endsWith('.png')) {
        res.setHeader('Content-Type', 'image/png');
    } else if (fileName.endsWith('.gif')) {
        res.setHeader('Content-Type', 'image/gif');
    } else if (fileName.endsWith('.mp4')) {
        res.setHeader('Content-Type', 'video/mp4');
    } else if (fileName.endsWith('.avi')) {
        res.setHeader('Content-Type', 'video/x-msvideo');
    } else if (fileName.endsWith('.mkv')) {
        res.setHeader('Content-Type', 'video/x-matroska');
    } else {
        return res.status(403).send('이미지 또는 동영상 파일이 아닙니다.');
    }

    // 파일을 클라이언트로 전송
    fs.createReadStream(filePath).pipe(res);
});

// Express 서버 실행
app.listen(port, () => {
    console.log(`서버가 http://localhost:${port} 에서 실행 중입니다.`);
});




// 이메일 전송 설정
const transporter = nodemailer.createTransport({
  service: 'Gmail', // 사용하는 이메일 제공자
  auth: {
    user: 'woldeog12@gmail.com', // 여기에 자신의 이메일 주소
    pass: '비공계', // 여기에 자신의 이메일 비밀번호
  },
});

// 이메일 전송 라우트
app.post('/sendEmail', (req, res) => {
  const { to, subject, text } = req.body;

  // 이메일 옵션 설정
  const mailOptions = {
    from: 'woldeog12@gmail.com', // 보내는 이메일 주소
    to: to, // 받는 이메일 주소
    subject: subject, // 이메일 제목
    text: text, // 이메일 내용
  };

  // 이메일 전송
  transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
      console.log('이메일 전송 실패:', error);
      res.status(500).json({ success: false, message: '이메일 전송 실패' });
    } else {
      console.log('이메일 전송 성공:', info.response);
      res.status(200).json({ success: true, message: '이메일 전송 성공' });
    }
  });
});
wss.on('connection', (ws) => {
  console.log('클라이언트가 연결했습니다.');

  // 클라이언트로부터 메시지 수신
  ws.on('message', (message) => {
    console.log(`받은 메시지: ${message}`);
    
    // 모든 클라이언트에게 메시지 전송
    wss.clients.forEach((client) => {
      if (client !== ws && client.readyState === WebSocket.OPEN) {
        client.send(message);
      }
    });
  });
});
app.get('/2', (req, res) => {
    res.render('2.ejs');
});

회원가입 구현 내용수정 이메일인증 코드 추가 아래 html 파일 첨부 해드릴게용!

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>회원가입</title>
    <link href="/public/u.css" rel="stylesheet">
</head>
<body>
    <h1>회원가입</h1>
    <form action="/join/membership" method="POST" id="signupForm">
        <label for="email">이메일:</label>
        <input type="email" name="email" required id="emailInput"><br>

        <!-- 이메일 인증 버튼 -->
        <button type="button" id="sendEmailButton">이메일 인증 요청</button><br>

        <label for="phoneNumber">전화번호:</label>
        <input type="tel" name="phoneNumber" required><br>

        <label for="address">주소:</label>
        <input type="text" name="address" required><br>

        <label for="name">이름:</label>
        <input type="text" name="name" required><br>

        <label for="id">ID:</label>
        <input type="text" name="id" required><br>

        <label for="password">비밀번호:</label>
        <input type="password" name="password" required><br>

        <label for="verificationCode">인증번호:</label>
        <input type="text" name="verificationCode" id="verificationCodeInput" required><br>

        <span id="randomNumber"></span><br> <!-- 랜덤 숫자를 표시할 곳 -->

        <input type="button" value="인증번호 확인" id="verifyCodeButton"><br>

        <input type="submit" value="회원가입" id="signupButton" disabled>
    </form>

    <script>
        const sendEmailButton = document.getElementById('sendEmailButton');
        const emailInput = document.getElementById('emailInput');
        const randomNumberElement = document.getElementById('randomNumber');
        const verificationCodeInput = document.getElementById('verificationCodeInput');
        const verifyCodeButton = document.getElementById('verifyCodeButton');
        const signupButton = document.getElementById('signupButton');

        let generatedVerificationCode = null;

        sendEmailButton.addEventListener('click', () => {
            const email = emailInput.value;
            if (email) {
                // 랜덤 6자리 숫자 생성
                generatedVerificationCode = generateRandomSixDigitNumber();

                // 이메일 내용 생성
                const emailContent = `seulnetlki 사이트 회원가입을 완료하려면 아래의 인증 코드를 입력하세요: ${generatedVerificationCode} seulnetlki 사이트 가입 해주셔서 감사합니다!`;

                // 이메일 주소와 내용을 백엔드로 전송하여 이메일을 전송
                fetch('/sendEmail', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({ to: email, subject: '이메일 인증 요청', text: emailContent }),
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        alert('이메일을 전송했습니다. 이메일을 확인하세요.');
                    } else {
                        alert('이메일 전송에 실패했습니다.');
                    }
                })
                .catch(error => {
                    console.error('이메일 전송 요청 실패:', error);
                    alert('이메일 전송 요청에 실패했습니다.');
                });
            }
        });

        verifyCodeButton.addEventListener('click', () => {
            const enteredCode = verificationCodeInput.value;
            if (enteredCode === generatedVerificationCode) {
                alert('인증번호가 일치합니다. 회원가입이 가능합니다.');
                signupButton.removeAttribute('disabled');
            } else {
                alert('인증번호가 일치하지 않습니다.');
            }
        });

        // 랜덤한 6자리 숫자 생성 함수
        function generateRandomSixDigitNumber() {
            const min = 000000;
            const max = 999999;
            return String(Math.floor(Math.random() * (max - min + 1)) + min);
        }
    </script>
</body>
</html>

이렇식으로 해서 인즈오드 발송 인증코드확인등 코드이다

728x90
반응형

'node.js웹사이트 만들기' 카테고리의 다른 글

node.js 만든 사이트 가비아 호스팅  (0) 2024.05.21
웹개발  (0) 2023.10.23
node.js 사이트 만들기  (1) 2023.10.11