https://github.com/loy124/express-mongodb-template
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 |