diff --git a/backend/app.js b/backend/app.js index b22273ce27e91d881c3499e3b6d4bc918e86da9b..a0c82fcfb6b29fc092dd2b9a8d12faee1db6e281 100644 --- a/backend/app.js +++ b/backend/app.js @@ -1,4 +1,3 @@ -require("dotenv").config(); var createError = require("http-errors"); var express = require("express"); var path = require("path"); @@ -6,6 +5,8 @@ var cookieParser = require("cookie-parser"); var logger = require("morgan"); var passport = require("passport"); var flash = require("connect-flash"); +var expressSession = require("express-session"); +var bodyParser = require("body-parser"); const mongoose = require("mongoose"); const mongooseAutoInc = require("mongoose-auto-increment"); @@ -22,7 +23,8 @@ mongooseAutoInc.initialize(mongoose.connection); var usersRouter = require("./routes/users"); var app = express(); - +app.use(bodyParser.json({ type: "application/json" })); +app.use(bodyParser.urlencoded({ extended: true })); // view engine setup app.set("views", path.join(__dirname, "views")); app.set("view engine", "jade"); @@ -31,13 +33,157 @@ app.use(logger("dev")); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); +app.use( + expressSession({ + secret: "me key", + resave: true, + saveUninitialized: true, + }) +); app.use(express.static(path.join(__dirname, "public"))); app.use(passport.initialize()); app.use(passport.session()); app.use(flash()); +var router = express.Router(); + +var UserModel = require("./models/user"); + +let LocalStrategy = require("passport-local").Strategy; + +passport.use( + "local-login", + new LocalStrategy( + { + usernameField: "email", + passwordField: "password", + passReqToCallback: true, + }, + async function (req, email, password, done) { + console.log("passport의 local-login 호출됨." + email + ", " + password); + try { + let u = await UserModel.findOne({ email: email, password: password }); + if (!u) { + console.log("이메일과 비밀번호가 일치하지 않습니다."); + return done( + null, + false, + req.flash("loginMessage", "이메일과 비밀번호를 다시 확인해 주세요.") + ); + } + console.log("계정과 비밀번호가 일치함"); + console.log(u); + return done(null, user); + } catch (err) { + console.log("로그인 인증과정에서 에러발생"); + console.log(err); + return done(err); + } + } + ) +); + +passport.use( + "local-signup", + new LocalStrategy( + { + usernameField: "email", + passwordField: "password", + passReqToCallback: true, + }, + async function (req, email, password, done) { + console.log("local-signup 실행됨."); + var paramName = req.body.name || req.query.name; + console.log( + "passport의 local-signup 호출됨 : " + + email + + ", " + + password + + ", " + + paramName + ); + try { + let u = await UserModel.findOne({ email: email }); + if (u) { + console.log("기존에 계정이 있음."); + return done( + null, + false, + req.flash("signupMessage", "계정이 이미 있습니다.") + ); + } else { + let user = new UserModel({ + email: email, + password: password, + name: paramName, + }); + let saved = await user.save(); + if (saved) { + console.log("사용자 데이터 추가함."); + return done(null, user); + } + } + } catch (err) { + console.log(err); + return done(err); + } + } + ) +); + +passport.serializeUser(function (user, done) { + console.log("serializeUser() 호출됨."); + console.dir(user); + done(null, user); +}); + +passport.deserializeUser(function (user, done) { + console.log("deserializeUser()호출됨."); + console.dir(user); + + done(null, user); +}); + +router.post( + "/login", + passport.authenticate("local-login", { + successRedirect: "http://localhost:3001/profile", + failureRedirect: "http://localhost:3000/login", + failureFlash: true, + }) +); + +router.post( + "/signup", + passport.authenticate("local-signup", { + successRedirect: "http://localhost:3001/profile", + failureRedirect: "http://localhost:3000/signup", + failureFlash: true, + }) +); + +router.get("/profile", function (req, res) { + console.log("/profile 패스 요청됨."); + console.log(req.user); + + if (!req.user) { + console.log("사용자 인증이 안 된 상태임."); + res.redirect("/"); + return; + } + + console.log("사용자 인증된 상태임"); + if (Array.isArray(req.user)) { + res.send(req.user[0]._doc); + } else { + res.send(req.user); + } +}); + +app.use("/", router); + //app.use("/", indexRouter); -app.use("/users", usersRouter); +//app.use("/", usersRouter); // catch 404 and forward to error handler app.use(function (req, res, next) { diff --git a/backend/package-lock.json b/backend/package-lock.json index 1e6469b400dd514b82de0996711f22ff1ff401bc..3f16688000ba63c5dd7dd4d56c8e0739688a7d35 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -323,6 +323,33 @@ } } }, + "express-session": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz", + "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==", + "requires": { + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.0", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + } + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -692,6 +719,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -928,6 +960,14 @@ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "optional": true }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/backend/package.json b/backend/package.json index 1e83fd863310aec43fcfd0eb1c3eef4510159e99..eb0c8a0dcd167f968a1aeb4f604dd791f2dd15b4 100644 --- a/backend/package.json +++ b/backend/package.json @@ -11,6 +11,7 @@ "debug": "~2.6.9", "dotenv": "^8.2.0", "express": "~4.16.1", + "express-session": "^1.17.1", "http-errors": "~1.6.3", "jade": "~1.11.0", "mongoose": "^5.10.15", diff --git a/backend/routes/users.js b/backend/routes/users.js index 0dd1230168844e6547f75fe4e73afe72a0df538c..b2fb0796fb698d408fe3ddf51e7b04acddc71a39 100644 --- a/backend/routes/users.js +++ b/backend/routes/users.js @@ -22,8 +22,8 @@ passport.use( console.log("이메일과 비밀번호가 일치하지 않습니다."); return done( null, - false, - req.flash("loginMessage", "이메일과 비밀번호를 다시 확인해 주세요.") + false + //req.flash("loginMessage", "이메일과 비밀번호를 다시 확인해 주세요.") ); } console.log("계정과 비밀번호가 일치함"); @@ -47,6 +47,7 @@ passport.use( passReqToCallback: true, }, async function (req, email, password, done) { + console.log("local-signup 실행됨."); var paramName = req.body.name || req.query.name; console.log( "passport의 local-signup 호출됨 : " + @@ -62,8 +63,8 @@ passport.use( console.log("기존에 계정이 있음."); return done( null, - false, - req.flash("signupMessage", "계정이 이미 있습니다.") + false + //req.flash("signupMessage", "계정이 이미 있습니다.") ); } else { let user = new UserModel({ @@ -98,36 +99,40 @@ passport.deserializeUser(function (user, done) { done(null, user); }); -router.post("/login", function (req, res, next) { - passport.authenticate("local-login", function (err, user, info) { - if (err) { - console.log(err); - return next(err); - } - - if (user) { - console.log("req.user : " + JSON.stringify(user)); - let json = JSON.parse(JSON.stringify(user)); - - req.logIn(user, function (err) { - if (err) { - return next(err); - } - }); - } else { - console.log("login fail!!!!!!!!!!!!!!!"); - res.send([]); - } - })(req, res, next); -}); +router.post( + "/login", + passport.authenticate("local-login", { + successRedirect: "http://localhost:3000/profile", + failureRedirect: "http://localhost:3000/login", + failureFlash: true, + }) +); router.post( "/signup", passport.authenticate("local-signup", { - successRedirect: "/profile", - failureRedirect: "/signup", + successRedirect: "http://localhost:3000/profile", + failureRedirect: "http://localhost:3000/signup", failureFlash: true, }) ); +router.get("/profile", function (req, res) { + console.log("/profile 패스 요청됨."); + console.log(req.user); + + if (!req.user) { + console.log("사용자 인증이 안 된 상태임."); + res.redirect("/"); + return; + } + + console.log("사용자 인증된 상태임"); + if (Array.isArray(req.user)) { + res.send(req.user[0]._doc); + } else { + res.send(req.user); + } +}); + module.exports = router; diff --git a/frontend/.eslintcache b/frontend/.eslintcache index 2fee2ea6fb80ba047c11c1f371cafc4d4cedfd39..9dda2776f734e83395113848831890043f578170 100644 --- a/frontend/.eslintcache +++ b/frontend/.eslintcache @@ -1 +1 @@ -[{"C:\\WYH\\frontend\\src\\reportWebVitals.js":"1","C:\\WYH\\frontend\\src\\App.js":"2","C:\\WYH\\frontend\\src\\index.js":"3","C:\\WYH\\frontend\\src\\Home.js":"4","C:\\WYH\\frontend\\src\\Signup.js":"5","C:\\WYH\\frontend\\src\\Login.js":"6","C:\\WYH\\frontend\\src\\Profile.js":"7"},{"size":362,"mtime":1606157613272,"results":"8","hashOfConfig":"9"},{"size":932,"mtime":1606312284464,"results":"10","hashOfConfig":"9"},{"size":544,"mtime":1606240034288,"results":"11","hashOfConfig":"9"},{"size":370,"mtime":1606296711314,"results":"12","hashOfConfig":"9"},{"size":1533,"mtime":1606312007071,"results":"13","hashOfConfig":"9"},{"size":1175,"mtime":1606312363487,"results":"14","hashOfConfig":"9"},{"size":573,"mtime":1606311449946,"results":"15","hashOfConfig":"9"},{"filePath":"16","messages":"17","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"10w9ldj",{"filePath":"18","messages":"19","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"20","messages":"21","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"22","messages":"23","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"24","messages":"25","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"26","messages":"27","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"28","messages":"29","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"C:\\WYH\\frontend\\src\\reportWebVitals.js",[],"C:\\WYH\\frontend\\src\\App.js",["30"],"C:\\WYH\\frontend\\src\\index.js",[],"C:\\WYH\\frontend\\src\\Home.js",["31"],"C:\\WYH\\frontend\\src\\Signup.js",[],"C:\\WYH\\frontend\\src\\Login.js",[],"C:\\WYH\\frontend\\src\\Profile.js",[],{"ruleId":"32","severity":1,"message":"33","line":1,"column":17,"nodeType":"34","messageId":"35","endLine":1,"endColumn":26},{"ruleId":"32","severity":1,"message":"36","line":2,"column":10,"nodeType":"34","messageId":"35","endLine":2,"endColumn":15},"no-unused-vars","'Component' is defined but never used.","Identifier","unusedVar","'Route' is defined but never used."] \ No newline at end of file +[{"C:\\WYH\\frontend\\src\\reportWebVitals.js":"1","C:\\WYH\\frontend\\src\\App.js":"2","C:\\WYH\\frontend\\src\\index.js":"3","C:\\WYH\\frontend\\src\\Home.js":"4","C:\\WYH\\frontend\\src\\Signup.js":"5","C:\\WYH\\frontend\\src\\Login.js":"6","C:\\WYH\\frontend\\src\\Profile.js":"7"},{"size":362,"mtime":1606157613272,"results":"8","hashOfConfig":"9"},{"size":932,"mtime":1606312284464,"results":"10","hashOfConfig":"9"},{"size":544,"mtime":1606240034288,"results":"11","hashOfConfig":"9"},{"size":370,"mtime":1606296711314,"results":"12","hashOfConfig":"9"},{"size":1596,"mtime":1606325070152,"results":"13","hashOfConfig":"9"},{"size":1235,"mtime":1606326896774,"results":"14","hashOfConfig":"9"},{"size":1006,"mtime":1606324675418,"results":"15","hashOfConfig":"9"},{"filePath":"16","messages":"17","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"10w9ldj",{"filePath":"18","messages":"19","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"20","messages":"21","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"22","messages":"23","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"24"},{"filePath":"25","messages":"26","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"27","messages":"28","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"29","messages":"30","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"C:\\WYH\\frontend\\src\\reportWebVitals.js",[],"C:\\WYH\\frontend\\src\\App.js",["31"],"C:\\WYH\\frontend\\src\\index.js",[],"C:\\WYH\\frontend\\src\\Home.js",["32"],"import React from \"react\";\r\nimport { Route, Link } from \"react-router-dom\";\r\n\r\nconst Home = () => {\r\n return (\r\n <div>\r\n <h1>WYB홈페이지입니다.</h1>\r\n <button>\r\n <Link to=\"/login\">로그인</Link>\r\n </button>\r\n <button>\r\n <Link to=\"/signup\">회원가입</Link>\r\n </button>\r\n </div>\r\n );\r\n};\r\n\r\nexport default Home;\r\n","C:\\WYH\\frontend\\src\\Signup.js",["33"],"C:\\WYH\\frontend\\src\\Login.js",["34"],"C:\\WYH\\frontend\\src\\Profile.js",[],{"ruleId":"35","severity":1,"message":"36","line":1,"column":17,"nodeType":"37","messageId":"38","endLine":1,"endColumn":26},{"ruleId":"35","severity":1,"message":"39","line":2,"column":10,"nodeType":"37","messageId":"38","endLine":2,"endColumn":15},{"ruleId":"35","severity":1,"message":"40","line":3,"column":10,"nodeType":"37","messageId":"38","endLine":3,"endColumn":14},{"ruleId":"35","severity":1,"message":"40","line":2,"column":10,"nodeType":"37","messageId":"38","endLine":2,"endColumn":14},"no-unused-vars","'Component' is defined but never used.","Identifier","unusedVar","'Route' is defined but never used.","'post' is defined but never used."] \ No newline at end of file diff --git a/frontend/src/Login.js b/frontend/src/Login.js index 1ed726b902e7821b68369385403d9a3ce9758369..57074fb150d9fa680ccbb550eeae7a754e5a9632 100644 --- a/frontend/src/Login.js +++ b/frontend/src/Login.js @@ -8,23 +8,23 @@ const Login = () => { const onChangeUsername = (e) => setUsername(e.target.value); const onChangePassword = (e) => setPassword(e.target.value); - const handleFormSubmit = () => { - const url = "/login"; - let formData = new FormData(); - formData.append("username", username); - formData.append("password", password); + // const handleFormSubmit = () => { + // const url = "/login"; + // let formData = new FormData(); + // formData.append("username", username); + // formData.append("password", password); - let config = { - headers: { - "content-type": "multipart/form-data", - }, - }; + // let config = { + // headers: { + // "content-type": "multipart/form-data", + // }, + // }; - return post(url, formData, config); - }; + // return post(url, formData, config); + // }; return ( - <form onSubmit={handleFormSubmit}> + <form action="http://localhost:3001/login" method="post"> <h1>로그인 화면</h1> 이메일: <input @@ -35,7 +35,7 @@ const Login = () => { ></input> 비밀번호: <input - type="pasword" + type="password" name="password" value={password} onChange={onChangePassword} diff --git a/frontend/src/Profile.js b/frontend/src/Profile.js index 15f07432e0c22edcf3182caffd53a13a995038d0..1eb2cd5a774a0124c96b701b34875a0eb555658e 100644 --- a/frontend/src/Profile.js +++ b/frontend/src/Profile.js @@ -1,28 +1,45 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; +import axios from "axios"; -const Profile = (login_info) => { +const Profile = () => { const [user, setUser] = useState(""); - fetch("/login", { - method: "post", - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - credentials: "same-origin", - body: JSON.stringify(login_info), - }) - .then((res) => res.json()) - .then((data) => { - console.dir(data); - setUser(data); - }); - - return ( - <div> - <h1>{user.username}</h1> - <h1>{user.nicname}</h1> - </div> - ); + useEffect(() => { + const fetchData = async () => { + const result = await axios("http://localhost:3000/profile"); + console.dir(result); + setUser(result.data); + }; + + fetchData(); + }, []); + + return <div>{user}</div>; }; +// const Profile = (login_info) => { +// const [user, setUser] = useState(""); + +// fetch("/profile", { +// method: "get", +// headers: { +// "Content-Type": "application/json; charset=utf-8", +// }, +// credentials: "same-origin", +// body: JSON.stringify(login_info), +// }) +// .then((res) => res.json()) +// .then((data) => { +// console.dir(data); +// setUser(data); +// }); + +// return ( +// <div> +// <h1>{user.username}</h1> +// <h1>{user.nicname}</h1> +// </div> +// ); +// }; + export default Profile; diff --git a/frontend/src/Signup.js b/frontend/src/Signup.js index d150c92b3a7134707a345f7610796ba71dcb3170..5b65fe00f66fad06601db993b58d66461af31978 100644 --- a/frontend/src/Signup.js +++ b/frontend/src/Signup.js @@ -11,24 +11,24 @@ const Signup = () => { const onChangeNicname = (e) => setNicname(e.target.value); const onChangePassword = (e) => setPassword(e.target.value); - const handleFormSubmit = () => { - const url = "/signup"; - const formData = new FormData(); - formData.append("username", username); - formData.append("password", password); - formData.append("nicname", nicname); + // const handleFormSubmit = () => { + // const url = "/signup"; + // const formData = new FormData(); + // formData.append("username", username); + // formData.append("password", password); + // formData.append("nicname", nicname); - const config = { - headers: { - "content-type": "multipart/form-data", - }, - }; + // const config = { + // headers: { + // "content-type": "multipart/form-data", + // }, + // }; - return post(url, formData, config); - }; + // return post(url, formData, config); + // }; return ( - <form onSubmit={handleFormSubmit}> + <form action="http://localhost:3001/signup" method="post"> <h1>회원가입</h1> 이메일: <input