회원가입을 하면 info.txt 파일에 "//"로 구분하여 정보가 저장되도록 하고, 해당 파일 정보로 로그인이 되도록 하기
먼저, npm(node package manager)를 설치한다.
npm init
그 다음 프로젝트에 필요한 dependeny를 설치한다.
npm install express
npm install ejs
npm install body-parser
MVC 패턴에 필요한 폴더를 생성해주고 main index.js 파일을 생성한다.
/* index.js */
const express = require("express");
const app = express();
const port = 8080;
const bodyParser = require("body-parser");
app.set("view engine", "ejs");
app.use( express.static( "uploads" ));
app.use(express.urlencoded({extended: true}));
app.use( bodyParser.json() );
const router = require("./routes");
app.use("/", router);
app.get("/", function(req,res){
res.send("Index");
})
app.listen(port, () => {
console.log( "Server Port: ", port);
})
User model을 생성한다. post_join()은 회원가입 button을 눌러 POST 형식으로 폼 전송이 되었을 때 info.txt 파일에 회원정보를 작성되게 구현하고, post_login()은 info.txt 파일에 저장되어 있는 정보를 읽어와서 로그인이 되도록 한다.
/* ./model/User.js */
const fs = require("fs").promises;
exports.post_join = function( data ){
// console.log( data );
const {id, name, email, phoneNumber, password } = data;
fs.appendFile("./info.txt", `${id}//${name}//${email}//${phoneNumber}//${password}\n`, (err) => {
if (err) {
console.log(err);
res.status(400).send("err!!");
}
});
}
exports.post_login = async function( data ){
var buffer = await fs.readFile("./info.txt");
return buffer.toString();
}
UserController.js 파일에서 각 경로에 따른 처리를 처리한다. join()은 처음 회원가입 화면으로 rendering되게 했다. post_join()은 User model의 post_join으로 req.body 데이터를 보내서 info.txt 파일을 작성하게 했다. 화면에 name 정보를 띄우기 위해 구조체 형식으로 name 정보를 보냈다. login()은 처음 로그인 화면이며, post_login()은 info.txt 파일에 있던 정보를 model를 통해 불러와 로그인처리 했다.
/* ./controller/UserController.js */
const User = require("../model/User");
exports.join = (req, res) => {
res.render("join");
}
exports.post_join = (req, res) => {
User.post_join(req.body);
res.render( "success_join", {name: req.body.name} );
}
exports.login = (req, res) => {
res.render( "login" );
}
exports.post_login = async (req, res) => {
var data = await User.post_login();
data = data.slice(0, -1).split("\n");
// console.log( "data:" , data );
for (var i=0; i<data.length; i++) {
var info = data[i].split("//");
if (info[0] == req.body.id && info[4] == req.body.password) {
return res.render("success_login", {id: req.body.id, msg: "로그인 되었습니다."})
}
}
return res.render("failed_login", {msg: "로그인 실패하였습니다."})
}
routes 폴더에서 index.js 파일을 생성한다. route 메소드를 사용해서 join(회원가입)과 login(로그인) 경로에 대한 GET 및 POST 메소드에 대해 정의한다.
/* ./routes/index.js */
const express = require("express");
const userRouter = express.Router();
const user = require("../controller/UserController");
userRouter.get("/join", user.join);
userRouter.post("/join", user.post_join);
userRouter.get("/login", user.login);
userRouter.post("/login", user.post_login);
module.exports = userRouter;
cannot create property '_locals on string '쥬비'
일단 회원가입을 진행하면, "name님 회원가입이 완료되었습니다." 라는 문구를 띄우려고 했는데 갑자기 이런 오류가 발생했다.
ejs.js 파일에서 <%=name%>이라고 받아놓고선, 데이터는 그냥 req.body.name으로 줘서 생긴 오류였다. 그래서 구조체로 {name: req.body.name}으로 데이터를 전달하는 방향으로 코드를 수정했다.
회원가입이 성공하면 info.txt파일에 정보가 저장된다
[ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
로그인이 성공했을 때, 로그인 성공 view로 이동이 되지만 위와 같은 오류가 발생했다. 이는 서버가 클라이언트에 둘 이상의 응답을 보내려고 할 때 발생하는 오류라고 한다.
/* .controller/UserControler.js */
exports.post_login = async (req, res) => {
var data = await User.post_login();
data = data.slice(0, -1).split("\n");
console.log( "data:" , data );
for (var i=0; i<data.length; i++) {
var info = data[i].split("//");
if (info[0] == req.body.id && info[4] == req.body.password) {
return res.render("success_login", {id: req.body.id, msg: "로그인 되었습니다."})
}
}
return res.render("failed_login", {msg: "로그인 실패하였습니다."})
}
for문에서 res.render를 이용해서 이미 rendering을 진행했는데, for문이 끝나고 난 후 또 다시 rendering을 시도하기 때문에 서버가 충돌하여 오류 메시지가 표시되었던 것이다. 그래서 코드에 return문을 추가하여 응답이 클라이언트에 전송되면 코드를 종료시킬 수 있도록 수정했다.