[Node.js] Express + MongoDB part#5 권한 체크 구현 Auth

Duboo·2022년 9월 29일
0

Server + DB

목록 보기
5/6
post-thumbnail
post-custom-banner

Authentication

글을 작성하거나 삭제하는 것 같은 권한이 필요한 컨텐츠와 로그인 유무등을 체크하기 위해 구현

이를 구현하기 위해서 클라이언트 쿠키에 저장된 토큰과 서버 데이터 베이스에 저장된 토큰이 일치하는지 확인합니다.


var token = jwt.sign(user._id.toHexString(), "hasVisited");

user._id + "hasVisited" = token 조합으로 인코드 되어 있는 토큰의 디코드를 통해 유저의 아이디를 추출해서 해당 아이디를 가진 유저의 DB에 같은 토큰이 존재하지는 확인하면 Authentication의 기능을 구현할 수 있습니다.

위와 같은 로직 위해서는 쿠키에 저장된 토큰을 서버에서 가져와 복호화를 진행합니다.

복호화를 통해 추출된 유저의 아이디로 데이터베이스안에 해당 아이디가 있는지 확인 후 있다면 쿠키에서 받아온 토큰을 동일하게 가지고 있는지 확인합니다.

Index.js

app.get("/api/users/auth", auth, (req, res) => { ... });

auth는 callback 함수를 실행하기 전에 중간에서 먼저 실행하는 역할을 하는데 이때 위에서 언급한 디코드 과정을 진행하며 디코드 구현을 위해 루트 디렉토리에서 middleware 폴더 > auth.js 를 생성합니다.

middleware/auth.js

const { User } = require("../models/User");

let auth = (req, res, next) => {
  // 클라이언트 쿠키에서 토큰 가져오기
  let token = req.cookies.hasVisited;
  
  // 토큰을 복호화 한후 일치하는 유저 찾기
  User.findByToken()
};

module.exports = { auth };

User.js

userSchema.statics.findByToken = function (token, cb) {
  var user = this;
  
  // 토큰을 decode 한다.
  jwt.verify(token, "hasVisited", function (err, decoded) {
    // 유저 아이디를 이용해 유저를 찾은 다음에
    // 클라이언트에서 가져온 token과 DB에 보관된 토큰이 일치하는지 확인
    user.findOne({ _id: decoded, token: token }, function (err, user) {
      if (err) return cb(err);
      cb(null, user);
    });
  });
};

코드 해석
유저의 토큰을 디코드하는 findByToken 생성
jwt.verify()을 통해 디코드를 실행
디코드된 유저의 아이디로 유저를 찾음(user.findOne)

auth.js 전체코드

const { User } = require("../models/User");

let auth = (req, res, next) => {
  // 클라이언트 쿠키에서 토큰 가져오기
  let token = req.cookies.hasVisited;

  // 토큰을 복호화 한후 일치하는 유저 찾기
  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 };

코드 해석
생성한 findByToken으로 유저를 찾고 유저가 있다면 유저의 토큰과 아이디에 값을 넣어주고
next()를 통해 미들웨어를 나갈 수 있게합니다.

Index.js - /api/users/auth

app.get("/api/users/auth", auth, (req, res) => {
  res.status(200).json({
    _id: req.user._id,
    email: req.user.email,
    name: req.user.name,
    title: req.user.title,
    isAuth: true,
  });
});

해당 코드에 도달하면 auth 미들웨어를 통과해 왔다는 의미로 Authentication이 true가 되니 200 코드를 넘겨주고 json 형태로 원하는 값을 넘겨줍니다.


권한이 true로 잘넘어오는지 포스트맨에서 확인

profile
둡둡
post-custom-banner

0개의 댓글