Node.js | React | MongoDB | Express (4)

Tony Kim·2022년 2월 4일
0
post-thumbnail

Node.js | React | MongoDB | Express (4)

1. Auth기능 만들기

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 }; 

2. 로그아웃 기능

순서
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)
    })
  })    
}
profile
Back-end-dev

0개의 댓글