Published 2022. 8. 25. 17:48
npm install jsonwebtoken --save
토큰 생성을 위한 jsonwebtoken 설치
npm install cookie-parser --save
쿠키에 토큰을 저장하기위한 cookie-parser 설치
app.post('/login', (req, res) => {
User.findOne({ email: req.body.email }, (err, user) => {
if (!user) {
return res.json({
loginSuccess: false,
message: "입력한 이메일에 해당하는 유저가 없습니다."
})
}
user.comparePassword(req.body.password, (err, isMatch) => {
if (!isMatch) {
return res.json({ loginSuccess: false, message: "비밀번호가 틀렸습니다." })
} else {
user.generateToken((err, user) => {
if (err) { return res.status(400).send(err) };
//쿠키, 로컬스토리지 등에 토큰 저장 가능하지만 여기서는 쿠키에 넣을것임
res.cookie("x_auth", user.token)
.status(200)
.json({ loginSuccess: true, userId: user._id });
});
}
})
})
})
post로 전달할 것이기 때문에 app.post에 경로를 login으로 만들어준다.
첫번째 findOne은 입력한 이메일과 DB속 email에 매칭하는 이메일이 없을 시 false를 돌려준다.
두번째 comparePassword도 입력한 비밀번호와 암호화된 비밀번호가 일치하는지 확인해주고
그 안에 token을 생성해 쿠키에 저장해두는 역할을 한다.
그 함수들은 User.js에서 만들었다
userSchema.methods.comparePassword = function (plainPassword, cb) {
bcrypt.compare(plainPassword, this.password, function (err, isMatch) {
if (err) return cb(err);
cb(null, isMatch)
})
}
userSchema.methods.generateToken = function (cb) {
var user = this;
var token = jwt.sign(user._id.toHexString(), 'secretToken');
user.token = token;
user.save(function (err, user) {
if (err) return cb(err);
cb(null, user);
})
}
아까 설치한 토큰과 쿠키파서를 이용해 토큰을 생성했다.
/login 실행 결과는 이러하다
Authentication 기능 추가
middleware 기능을 하는 auth이기 때문에 따로 middleware 폴더를 만들어서 분리시켰다.
const { User } = require('../models/User');
let auth = (req, res, next) => {
//쿠키에서 토큰을 가져온다
let token = req.cookies.x_auth;
User.findByToken(token, (err, user) => {
if (err) throw err;
if (!user) return res.json({ isAuth: false, error: true });
req.token = token;
req.user = user;
next();
})
}
module.exports = { auth }
그리고 어디서든 불러올 수 있게 exports를 해주었다.
userSchema.statics.findByToken = function (token, cb) {
var user = this;
//token decoded
jwt.verify(token, 'secretToken', function (err, decoded) {
// 유저아이디를 이용해 유저를 찾은 다음
// 클라이언트에서 가져온 token과 DB token과 비교
user.findOne({ "_id": decoded, "token": token }, function (err, user) {
if (err) return cb(err);
cb(null, user);
})
})
}
users에서도 복호화하여 비교할 수 있게 findByToken을 생성하여 코드를 작성해주었고.
app.get('/api/users/auth', auth, (req, res) => {
res.status(200).json({
_id: req.user._id,
isAdmin: req.user.role === 0 ? false : true,
isAuth: true,
email: req.user.email,
name: req.user.name,
lastname: req.user.lastname,
role: req.user.role,
image: req.user.image
})
})
마지막으로 index.js에 auth.js를 임포트하고 URL까지 만들어주었다.
나중에 분리작업 시 편리하기위해서 /api/users를 다른 URL들에도 추가해주었다.
로그아웃 만들기
로그아웃 라우터를 만들것이다.
로그아웃에 해당하는 유저를 찾아 토큰을 삭제하는 기능을 구현해야한다.
app.get('/api/users/logout', auth, (req, res) => {
//미들웨어에서 가져옴
User.findOneAndUpdate(
{ _id: req.user._id },
{ token: "" },
(err, user) => {
if (err) return res.json({ success: false, err });
return res.status(200).send({
success: true
})
}
)
})
로그인시에 생성되었던 토큰이 로그아웃하면 DB에서 ""로 업데이트되어 사라지는것을 확인 할 수 있다.
반응형
'개발 > Javascript' 카테고리의 다른 글
[Node] 백&프론트서버 두 개를 한번에 열기 (3) | 2022.08.26 |
---|---|
[Node] Data흐름과 axios, proxy서버 사용하기 (0) | 2022.08.26 |
[Node] Bcrypt 사용해서 암호화하기 (0) | 2022.08.24 |
[Node] npm 과 npx (0) | 2022.08.22 |
[Node] Nodemon 설치 (1) | 2022.08.21 |