https://github.com/loy124/express-mongodb-template
loy124/express-mongodb-template
express 와 mongodb를 연동해서 회원가입및 로그인을 구현해둔 예제입니다. Contribute to loy124/express-mongodb-template development by creating an account on GitHub.
github.com
express의 미들웨어 기능을 활용해서
회원정보 수정, 혹은 로그인 권한이 있어야지만 수행할수 있는 기능들이 시작되기전에 미들웨어를 한번 거치고 검증후 실행 될수 있게 미들웨어를 구현한다.
먼저 쿠키에있는 jwt의 값을 가져오려면
cookie-parser을 다운로드 해준다
npm i cookie-parser --save
server.js에서 해당과같이 require로 가져온 후 app.use를 사용해주면된다.
const express = require("express");
const app = express();
const port = 9000;
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const mongoose = require("mongoose");
const { User } = require("./models/User");
const { auth } = require("./middleware/auth");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());
먼저 User.js에 토큰을 찾아서 작업을 수행하는 findByToken을 만들어준다.
User.js
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const saltRounds = 10;
const jwt = require("jsonwebtoken");
const userSchema = mongoose.Schema({
name: {
type: String,
maxlength: 50,
},
email: {
type: String,
trim: true, //dhsdb 1541 @naver.com 을 dhsdb1541@naver.com로 trim
unique: 1,
},
password: {
type: String,
minLength: 5,
},
lastName: {
type: String,
maxLength: 50,
},
role: {
type: Number,
default: 0,
},
image: String,
token: {
type: String,
},
tokenExp: {
type: Number,
},
});
//save 메소드가 실행되기전에 비밀번호를 암호화하는 로직을 짜야한다
userSchema.pre("save", function (next) {
let user = this;
//model 안의 paswsword가 변환될때만 암호화
if (user.isModified("password")) {
bcrypt.genSalt(saltRounds, function (err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
} else {
next();
}
});
userSchema.methods.comparePassword = function (plainPassword) {
//plainPassword를 암호화해서 현재 비밀번호화 비교
return bcrypt
.compare(plainPassword, this.password)
.then((isMatch) => isMatch)
.catch((err) => err);
};
userSchema.methods.generateToken = function () {
const token = jwt.sign(this._id.toHexString(), "secretToken");
this.token = token;
return this.save()
.then((user) => user)
.catch((err) => err);
};
userSchema.statics.findByToken = function (token) {
let user = this;
//secretToken을 통해 user의 id값을 받아오고 해당 아이디를 통해
//Db에 접근해서 유저의 정보를 가져온다
return jwt.verify(token, "secretToken", function (err, decoded) {
return user
.findOne({ _id: decoded, token: token })
.then((user) => user)
.catch((err) => err);
});
};
const User = mongoose.model("User", userSchema);
module.exports = { User };
statics를 사용해 항시 사용이 가능하도록 메소드를 제작하고
jwt.verify(토큰, "지정해둔 특정 문자")를 넣어서 decoded된 값을 통해 _id를 db와 조회해서 값을 넘겨준다.
해당 메소드는 미들웨어에서 사용할예정이다
미들웨어 폴더를 생성하고 auth.js를 만들어준다.
auth.js
const { User } = require("../models/User");
let auth = (req, res, next) => {
let token = req.cookies.x_auth;
User.findByToken(token)
.then((user) => {
if (!user) return res.json({ isAuth: false, error: true });
req.token = token;
req.user = user;
next();
})
.catch((err) => {
throw err;
});
};
module.exports = { auth };
token을 찾으면 req.token에 token과 user 정보를 넣어준다.
해당 auth는
/auth 혹은 로그아웃 회원정보 수정및 여러가지 요소에 인증을 위한 요소로 사용이 된다.
const express = require("express");
const app = express();
const port = 9000;
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const mongoose = require("mongoose");
const { User } = require("./models/User");
const { auth } = require("./middleware/auth");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());
//이곳에 mongodb 사이트에서 카피한 주소를 이곳에 넣으면 된다.
const dbAddress =
"mongodb+srv://root:root@cluster0-f3nrh.mongodb.net/<dbname>?retryWrites=true&w=majority";
mongoose
.connect(dbAddress, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false,
})
.then(() => console.log("MongoDB Connected"))
.catch((err) => console.log(err));
app.get("/", (req, res) => res.send("Hello world!!!!"));
app.post("/register", (req, res) => {
//회원가입을 할때 필요한것
//post로 넘어온 데이터를 받아서 DB에 저장해준다
const user = new User(req.body);
user.save((err, userInfo) => {
if (err) return res.json({ success: false, err });
return res.status(200).json({ success: true });
});
});
app.post("/login", (req, res) => {
//로그인을할때 아이디와 비밀번호를 받는다
User.findOne({ email: req.body.email }, (err, user) => {
if (err) {
return res.json({
loginSuccess: false,
message: "존재하지 않는 아이디입니다.",
});
}
user
.comparePassword(req.body.password)
.then((isMatch) => {
if (!isMatch) {
return res.json({
loginSuccess: false,
message: "비밀번호가 일치하지 않습니다",
});
}
//비밀번호가 일치하면 토큰을 생성한다
//해야될것: jwt 토큰 생성하는 메소드 작성
user
.generateToken()
.then((user) => {
res.cookie("x_auth", user.token).status(200).json({
loginSuccess: true,
userId: user._id,
});
})
.catch((err) => {
res.status(400).send(err);
});
})
.catch((err) => res.json({ loginSuccess: false, err }));
});
});
//auth 미들웨어를 가져온다
//auth 미들웨어에서 필요한것 : Token을 찾아서 검증하기
app.get("/auth", auth, (req, res) => {
//auth 미들웨어를 통과한 상태 이므로
//req.user에 user값을 넣어줬으므로
res.status(200).json({
_id: req._id,
isAdmin: req.user.role === 09 ? false : true,
isAuth: true,
email: req.user.email,
name: req.user.name,
lastname: req.user.lastname,
role: req.user.role,
image: req.user.image,
});
});
app.listen(port, () => console.log(`listening on port ${port}`));
로그인이 된상태에서 auth get 요청을 보내주면
정상적으로 동작하는것을 알 수 있다.
'Node.js > node 활용하기' 카테고리의 다른 글
node multer을 활용한 파일 업로드 (0) | 2020.08.23 |
---|---|
express mongodb 활용하기 - 로그아웃 구현하기, cors 적용하기 (마무리) (0) | 2020.06.28 |
express mongodb 활용하기 - 로그인 기능 만들기 (jwt) (5) | 2020.06.28 |
express mongodb 활용하기 - 회원가입 구현하기(bcrypt로 암호화) (5) | 2020.06.27 |
express mongodb 활용하기 - express 기초 셋팅및 mongodb 연결하기 (2) | 2020.06.24 |