rootProject
ㄴconfig/
ㄴpassport.js
ㄴcontroller/
ㄴuser.js
ㄴmigrations/
ㄴmodels/
ㄴ User.js
ㄴ index.js
ㄴroutes/
ㄴ user.js
ㄴseeders/
ㄴviews/
ㄴuser/
ㄴjoin.ejs
ㄴlogin.ejs
ㄴmypage.ejs
ㄴindex.js
이메일을 유저 id로 사용함
config/dbconfig.json
{
"development": {
"username": "",
"password": "",
"database": "",
"host": "",
"dialect": "mysql"
},
"test": {
"username": "",
"password": "",
"database": "",
"host": "",
"dialect": "mysql"
},
"production": {
"username": "",
"password": "",
"database": "",
"host": "",
"dialect": "mysql"
}
}
models/user.js
const Sequelize = require('sequelize');
module.exports = class User extends Sequelize.Model {
static init(sequelize) {
return super.init({
usr_email: {
type: Sequelize.STRING(50),
primaryKey: true,
allowNull: false,
unique: true
},
usr_password: {
type: Sequelize.STRING(60),
allowNull: false,
unique: false
},
usr_name: {
type: Sequelize.STRING(20),
allowNull: false,
unique: true
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
unique: false
},
change_pass: {
type: Sequelize.DATE,
allowNull: true,
unique: false
},
is_super: {
type: Sequelize.CHAR(1),
unique: false,
defaultValue: 'N'
},
activate_yn: {
type: Sequelize.CHAR(1),
allowNull: true,
unique: false,
defaultValue: 'Y'
},
},
{
sequelize,
timestamps: false,
underscored: false,
modelName: 'User',
tableName: 'user',
paranoid: false,
charset: 'utf8mb4',
collate: 'utf8mb4_general_ci'
});
}
};
models/index.js
const Sequelize = require('sequelize');
const User = require('./User');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/dbconfig')[env];
const db = {};
const sequelize = new Sequelize(config.database, config.username, config.password, config);
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.User = User;
db.Project = Project;
User.init(sequelize);
module.exports = db;
index.js
const express = require('express');
const bodyParser = require('body-parser');
const methodOverride = require('method-override');
const app = express();
//DB connect
const { sequelize } = require('./models');
sequelize.sync({ force : false})
.then(() => {
console.log('connection success');
})
.catch((err) => {
console.error(`connection fail - ${err}`);
});
// Other settings
app.set('view engine', 'ejs');
app.use(express.static(__dirname+'/public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(methodOverride('_method'));
// Routes
app.use('/user', require('./routes/user'));
app.use('/', require('./routes/menu'));
const port = 3000;
app.listen(port, function(){
console.log('server on! http://localhost:'+port);
});
routes/user.js
const express = require('express');
const router = express.Router();
const { join } = require('../controller/user');
//회원가입 페이지
router.get('/join', (req, res) => {
res.render('user/join');
})
//회원가입 진행
router.post('/joinProc', join);
module.exports = router;
controller/user.js
const bcrypt = require('bcryptjs');
const User = require('../models/User');
exports.join = function (req, res) {
let { email, password, passwordConfirmation, name } = req.body;
//비밀번호 암호화
password = bcrypt.hashSync(password)
//저장
var now = new Date();
User.create({
usr_email: email,
usr_password: password,
usr_name: name,
created_at: now
})
.then(()=>{
res.redirect('/user/login');
})
.catch((err) => {
throw err;
}) ;
};
/views/user/join.ejs
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
<h3>Join</h3>
<form action="/user/joinProc" method="post">
<div>
<label>Email</label>
<div>
<input type="text" id="email" name="email" value="">
</div>
</div>
<div>
<label for="password">Password</label>
<div >
<input type="password" id="password" name="password" value="" >
</div>
</div>
<div>
<label for="passwordConfirmation" >Password Confirmation</label>
<div>
<input type="password" id="passwordConfirmation" name="passwordConfirmation" value="">
</div>
</div>
<div>
<label for="username">Username</label>
<div>
<input type="text" id="name" name="name" value="">
</div>
</div>
<div>
<button type="submit" >Submit</button>
</div>
</form>
</div>
</body>
</html>
config/passport.js
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
const User = require('../models/User');
const bcrypt = require('bcryptjs');
//로그인할 때마다 email 저장
passport.serializeUser((user, done) => {
done(null, user.usr_email);
})
//email로 유저 객체 불러오기
passport.deserializeUser((email, done) => {
User.findByPk(email).then( user =>{
if(user) {
done(null, user.get());
} else {
done(null, false);
}
});
})
passport.use(
new LocalStrategy(
{
usernameField: "email",
passwordField: "password",
passReqToCallback: true,
},
async (req, email, password, done) => {
User.findOne({
where: {
usr_email: email
}
}).then((user)=> {
if (user && bcrypt.compareSync(password, user.usr_password)) {
return done(null, user.dataValues);
} else {
return done(null, false);
}
}).catch(err => {
return done(err);
})
}
)
);
module.exports = passport;
index.js
//DB connect
...
// 세션
const session = require("express-session");
app.use(session({
resave: false,
saveUninitialized: true,
secret: 'secret'
}));
//passport
const passport = require("./config/passport");
app.use(passport.initialize());
app.use(passport.session());
//모든 라우트에서 실행되는 미들웨어
app.use((req, res, next) => {
res.locals.isAuthenticated = req.isAuthenticated(); //locals에 저장하면 view에서 바로 사용가능
res.locals.currentUser = req.user;
next();
})
...
//Other Settings
routes/user.js
//import modules
...
//로그인
router.get('/login', function (req, res) {
res.render('user/login');
})
router.post('/loginProc',
passport.authenticate('local', {
successRedirect: "/user/mypage",
failureRedirect: "/user/login",
failureFlash: true })
);
//마이 페이지
router.get('/mypage', (req,res) => {
const user = res.locals.currentUser
if (user === undefined) { //로그인X
res.render('user/login');
} else {
res.render('user/mypage');
}
});
//로그아웃
router.get('/logout',function (req, res) {
req.logout();
res.redirect('/');
});
...
//join route
/views/user/login.ejs
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
<h3>Login</h3>
<form action="/user/loginProc" method="post">
<div>
<label for="email">Email</label>
<div>
<input type="text" id="email" name="email" value="">
</div>
</div>
<div>
<label for="password">Password</label>
<div>
<input type="password" id="password" name="password" value="">
</div>
</div>
<div>
<input type="submit" value="Submit">
</div>
</form>
</div>
</body>
</html>
/views/user/mypage.ejs
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
<h3><%= currentUser.usr_name %> 님의 페이지</h3>
</div>
</body>
</html>