Auth기능 필요한 이유
token
ex)
A페이지 -> B페이지 이동할 때 유저가 B페이지 갈 수 있는지 체크하기 위해 클라이언트에서 서버에 쿠키에 담긴 토큰을 전달
서버쪽에서 토큰 전달할 때 토큰이 인코드 되어있는 상태이기 때문에 디코드하면 userId가 나옴
userId를 가진 유저 데이터베이스에 토큰이 있다면 인증이 맞다 / 없다면 유저가 아니다
순서
1) Cookie에 저장된 Token을 Server로 가져와서 복호화
2) 복호화하면 userId 나오고 해당 userId를 데이터베이스 User Collection에서 찾은 후 쿠키에서 받아온 token이 유저한테 있는지 확인
index.js
const {auth} = require("./middleware/auth") app.get('/api/users/auth', auth, (req, res) => { // 미들웨어 (엔드포인트에 req받기 전에 중간에서 별도로 해주는 것) // 여기까지 왔다는 얘기는 Authentication이 true라는 말 res.status(200).json({ _id: req.user._id, isAdmin: req.user.role === 0 ? false : true, // 0이면 일반유저 isAuth: true, email: req.user.email, name: req.user.name, lastname: req.user.lastname, role: req.user.role, image:req.user.image }) })
User.js
userSchema.statics.findByToken = function(token, cb) { // jsonwebtoken usage var user = this; //토큰을 decode jwt.verify(token, 'secretToken', function(err, decoded) { //유저 아이디를 이용해서 유저를 찾은 다음에 //클라이언트에서 가져온 token과 DB에 보관된 토큰이 일치하는지 확인 user.findOne({"_id": decoded, "token": token}, function (err, user) { if (err) return cb(err); cb(null, user) }) }) }
middleware파일 생성 > auth.js
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; //유저가 없으면 인증 NO if(!user) return res.json({ isAuth: false, error: true}) //유저가 있으면 인증 OK req.token = token; // request에 넣어주는이유: index.js에서 token과 user 사용하기 위해 req.user = user; next() // index.js 미들웨어에서 다음으로 넘어갈 수 있도록 }) } module.exports = { auth };
순서
1) 로그아웃 route 만들기
2) 로그아웃하려는 유저를 데이터베이스에서 찾기
3) 그 유저의 토큰을 데이터 베이스에서 지워주기
토큰을 지우는 이유
auth기능에서 인증할 때 쿠키 토큰과 서버(db) 토큰 비교해서 인증했는데, 토큰이 db에 없으면 클라이언트에서 가져온 토큰이 맞지 않기 때문에 인증이 안됨
-> 로그인 기능이 풀림
index.js
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 }) }) })
User.js
userSchema.statics.findByToken = function(token, cb) { // jsonwebtoken usage var user = this; //토큰을 decode jwt.verify(token, 'secretToken', function(err, decoded) { //유저 아이디를 이용해서 유저를 찾은 다음에 //클라이언트에서 가져온 token과 DB에 보관된 토큰이 일치하는지 확인 user.findOne({"_id": decoded, "token": token}, function (err, user) { if (err) return cb(err); cb(null, user) }) }) }