Jeongmin Seo

merge feature/login_signup branch

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
**node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
.env.production
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
\ No newline at end of file
"use strict";
//모듈
const express = require("express");
const bodyParser = require("body-parser");
//환경변수 (운영체제간 gap 없애고자)
const dotenv = require("dotenv");
dotenv.config();
const app = express();
//라우팅
const home = require("./src/routes/home");
// 앱 세팅
app.set("views", "./src/views");
app.set("view engine", "ejs");
app.use(express.static(`${__dirname}/src/public`));
app.use(bodyParser.json());
//url통해 전달되는 데이터에 한글, 공백 등의 문자 오류 해결
app.use(bodyParser.urlencoded({extended: true}));
app.use("/", home); //미들웨어 등록해주는 method
module.exports = app;
\ No newline at end of file
"use strict";
const app = require("../app");
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log("서버 가동");
});
\ No newline at end of file
This diff is collapsed. Click to expand it.
{
"name": "login",
"version": "1.0.0",
"main": "app.js",
"bin": {
"login": "www.js"
},
"dependencies": {
"body-parser": "^1.20.0",
"dotenv": "^16.0.1",
"ejs": "^3.1.8",
"express": "^4.18.1",
"mysql": "^2.18.1"
},
"devDependencies": {},
"scripts": {
"start": "nodemon ./bin/www.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"keywords": [],
"description": ""
}
const mysql = require("mysql");
const db = mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
});
db.connect();
module.exports = db;
\ No newline at end of file
'use strict';
//for DB manipulate
const UserStorage = require("./UserStorage");
class User {
constructor(body) {
this.body = body;
}
async login() {
const client = this.body;
try {
const {id, password} = await UserStorage.getUserInfo(client.id);
// console.log(id, password);
if (id) {
if (id === client.id && password === client.password) {
return { success: true};
}
return { success : false, msg: "비밀번호가 틀렸습니다."};
}
return {success: false, msg: "존재하지 않는 아이디입니다."};
} catch (err) {
return {success: false, msg: err};
}
}
async register() {
const client = this.body;
try {
const response = await UserStorage.save(client);
// console.log(response);
return response;
} catch (err) {
return {success: false, msg : err};
}
}
}
module.exports = User;
\ No newline at end of file
'use strict';
//for DB CRUD
const db = require("../config/db");
class UserStorage {
// static getUsers(isAll, ...fields) {
// }
static getUserInfo(id) {
return new Promise((resolve, reject) => {
const query = "SELECT * FROM users WHERE id = ?;";
db.query(query, [id], (err, data) => {
if (err) reject(`${err}`);
// console.log(data[0]);
resolve(data[0]);
});
});
}
static async save(userInfo) {
return new Promise((resolve, reject) => {
const query = "INSERT INTO users(id, name, password) VALUES(?, ?, ?);";
db.query(
query,
[userInfo.id, userInfo.name, userInfo.password],
(err, data) => {
if (err) reject(`${err}`);
// console.log(data[0]);
resolve({ success: true});
}
);
});
}
}
module.exports = UserStorage;
\ No newline at end of file
@import url(https://fonts.googleapis.com/css?family=Roboto:300);
.login-page {
width: 360px;
padding: 12% 0 0;
margin: auto;
}
.form {
position: relative;
z-index: 1;
background: #FFFFFF;
max-width: 360px;
margin: 0 auto 100px;
padding: 45px;
text-align: center;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
}
.form input {
font-family: "Roboto", sans-serif;
outline: 0;
background: #f2f2f2;
width: 100%;
border: 0;
margin: 0 0 15px;
padding: 15px;
box-sizing: border-box;
font-size: 14px;
}
.form #button {
font-family: "Roboto", sans-serif;
text-transform: uppercase;
outline: 0;
background: rebeccapurple;
width: 89%;
border: 0;
margin: 0 auto;
padding: 15px;
color: #FFFFFF;
font-size: 14px;
-webkit-transition: all 0.3 ease;
transition: all 0.3 ease;
cursor: pointer;
}
.form #button:hover,.form #button:active,.form #button:focus {
background: rebeccapurple;
}
.form .message {
margin: 15px 0 0;
color: #b3b3b3;
font-size: 12px;
}
.form .message a {
color: rebeccapurple;
text-decoration: none;
}
.form .register-form {
display: none;
}
.container {
position: relative;
z-index: 1;
max-width: 300px;
margin: 0 auto;
}
.container:before, .container:after {
content: "";
display: block;
clear: both;
}
.container .info {
margin: 50px auto;
text-align: center;
}
.container .info h1 {
margin: 0 0 15px;
padding: 0;
font-size: 36px;
font-weight: 300;
color: #1a1a1a;
}
.container .info span {
color: #4d4d4d;
font-size: 12px;
}
.container .info span a {
color: #000000;
text-decoration: none;
}
.container .info span .fa {
color: #EF3B3A;
}
/* #id::placeholder #password::placeholder {
color: black;
font-style: italic;
font-weight: bold;
} */
body {
background: rebeccapurple; /* fallback for old browsers */
/* background: rebeccapurple; */
background: linear-gradient(90deg, rebeccapurple 0%, rebeccapurple 0%);
font-family: "Roboto", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) */
\ No newline at end of file
@import url(https://fonts.googleapis.com/css?family=Roboto:300);
.login-page {
width: 360px;
padding: 8% 0 0;
margin: auto;
}
.form {
position: relative;
z-index: 1;
background: #FFFFFF;
max-width: 360px;
margin: 0 auto 100px;
padding: 45px;
text-align: center;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
}
.form input {
font-family: "Roboto", sans-serif;
outline: 0;
background: #f2f2f2;
width: 100%;
border: 0;
margin: 0 0 15px;
padding: 15px;
box-sizing: border-box;
font-size: 14px;
}
.form #button {
font-family: "Roboto", sans-serif;
text-transform: uppercase;
outline: 0;
background: rebeccapurple;
width: 89%;
border: 0;
margin: 0 auto;
padding: 15px;
color: #FFFFFF;
font-size: 14px;
-webkit-transition: all 0.3 ease;
transition: all 0.3 ease;
cursor: pointer;
}
.form #button:hover,.form #button:active,.form #button:focus {
background: rebeccapurple;
}
.form .message {
margin: 15px 0 0;
color: #b3b3b3;
font-size: 12px;
}
.form .message a {
color: rebeccapurple;
text-decoration: none;
}
.form .register-form {
display: none;
}
.container {
position: relative;
z-index: 1;
max-width: 300px;
margin: 0 auto;
}
.container:before, .container:after {
content: "";
display: block;
clear: both;
}
.container .info {
margin: 50px auto;
text-align: center;
}
.container .info h1 {
margin: 0 0 15px;
padding: 0;
font-size: 36px;
font-weight: 300;
color: #1a1a1a;
}
.container .info span {
color: #4d4d4d;
font-size: 12px;
}
.container .info span a {
color: #000000;
text-decoration: none;
}
.container .info span .fa {
color: #EF3B3A;
}
/* #id::placeholder #password::placeholder {
color: black;
font-style: italic;
font-weight: bold;
} */
body {
background: rebeccapurple; /* fallback for old browsers */
/* background: rebeccapurple; */
background: linear-gradient(90deg, rebeccapurple 0%, rebeccapurple 0%);
font-family: "Roboto", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) */
\ No newline at end of file
'use strict';
const id = document.querySelector("#id"),
password = document.querySelector("#password"),
loginBtn = document.querySelector("#button");
loginBtn.addEventListener("click", login);
function login() {
const req = {
id : id.value,
password : password.value,
};
fetch("/login", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(req),
})
.then((res) => res.json())
.then((res) => {
if (res.success) {
//성공하면 이동
location.href = "/";
} else {
alert(res.msg);
}
})
.catch((err) => {
console.error("로그인 중 에러 발생");
});
}
\ No newline at end of file
'use strict';
const id = document.querySelector("#id"),
name = document.querySelector("#name"),
password = document.querySelector("#password"),
confirmPassword = document.querySelector("#confirm-password"),
registerBtn = document.querySelector("#button");
registerBtn.addEventListener("click", register);
function register() {
if(!id.value) {
return alert("아이디를 입력해주세요.")
}
if(!name.value) {
return alert("이름을 입력해주세요.")
}
if(!password.value) {
return alert("비밀번호를 입력해주세요.")
}
if(!confirmPassword.value) {
return alert("비밀번호를 확인해주세요.")
}
if (password.value !== confirmPassword.value) {
return alert("비밀번호가 일치하지 않습니다.")
}
const req = {
id : id.value,
name : name.value,
password : password.value,
};
fetch("/register", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(req),
})
.then((res) => res.json())
.then((res) => {
if (res.success) {
//성공하면 이동
location.href = "/login";
} else {
alert(res.msg);
}
})
.catch((err) => {
console.error("회원가입 중 에러 발생");
});
}
\ No newline at end of file
"use strict";
const User = require("../../models/User");
const output = {
hello: (req, res) => {
res.render("home/index");
},
login: (req, res) => {
res.render("home/login");
},
register: (req, res) => {
res.render("home/register");
}
};
const process = {
login: async (req, res) => {
const user = new User(req.body);
const response = await user.login();
return res.json(response);
},
register: async (req, res) => {
const user = new User(req.body);
const response = await user.register();
return res.json(response);
},
// const id = req.body.id,
// password = req.body.password;
// const users = UserStorage.getUsers("id", "password");
// // console.log(UserStorage.getUsers("id", "password","name"));
// const response = {};
// if (users.id.includes(id)) {
// const idx = users.id.indexOf(id);
// if (users.password[idx] === password) {
// response.success = true;
// return res.json(response);
// }
// }
// response.success = false;
// response.msg = "로그인에 실패하였습니다."
// return res.json(response);
};
module.exports = {
output,
process,
};
\ No newline at end of file
"use strict";
const express = require("express");
const router = express.Router();
const ctrl = require("./home.ctrl");
router.get("/", ctrl.output.hello);
router.get("/login", ctrl.output.login);
router.get("/register", ctrl.output.register);
router.post("/login", ctrl.process.login);
router.post("/register", ctrl.process.register);
module.exports = router;
\ No newline at end of file
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
여기는 루트입니다.
</body>
</html>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/css/home/login.css" />
<script src="/js/home/login.js" defer></script>
<title>Document</title>
</head>
<body>
<div class="login-page">
<div class="form">
<!-- <form class="register-form">
<input type="text" placeholder="name" />
<input type="password" placeholder="password" />
<input type="text" placeholder="email address" />
<button>create</button>
<p class="message">Already registered? <a href="#">Sign In</a></p>
</form> -->
<form class="login-form">
<input id="id" type="text" placeholder="아이디" />
<input id="password" type="password" placeholder="비밀번호" />
<p id="button">LOGIN</p>
<p class="message">
계정이 없으신가요? <a href="/register">회원가입</a>
</p>
</form>
</div>
</div>
</body>
</html>
<!-- Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/css/home/register.css" />
<script src="/js/home/register.js" defer></script>
<title>Document</title>
</head>
<body>
<div class="login-page">
<div class="form">
<!-- <form class="register-form">
<input type="text" placeholder="name" />
<input type="password" placeholder="password" />
<input type="text" placeholder="email address" />
<button>create</button>
<p class="message">Already registered? <a href="#">Sign In</a></p>
</form> -->
<form class="login-form">
<input id="id" type="text" placeholder="아이디" />
<input id="name" type="text" placeholder="이름" />
<input id="password" type="password" placeholder="비밀번호" />
<input
id="confirm-password"
type="password"
placeholder="비밀번호 확인"
/>
<p id="button">SIGN UP</p>
<p class="message">계정이 있으신가요? <a href="/login">로그인</a></p>
</form>
</div>
</div>
</body>
</html>
<!-- Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) -->
{
"lockfileVersion": 1
}