인증은 유저가 누구인지 확인하는 절차를 말한다. 각 페이지에서 어떤 유저인지에 따라 권한이 달라진다.
쉽게 설명하면 유저의 아이디와 비밀번호를 확인하는 절차이다.
앞서 회원가입과 로그인 기능을 구현하였고 로그인에 성공하면 토큰을 생성하고 쿠키(클라이언트)에 저장했다. 이 토큰을 가져와 복호화를 거쳐 토큰 생성에 사용한 아이디 userID를 찾고 DB에 저장된 토큰과 비교를 하여 맞다면 인증을 시켜주는 것이다. (로그인 라우터 마지막 포인트와 같은 이야기이다.)
// index.js
app.get('/api/users/auth', auth, (req, res) => {
// 미들웨어 통과 후의 작업, auth가 true
res.status(200).json({
_id: req.user._id,
isAdmin: req.user.role === 0 ? false : true,
isAuth: true,
email: req.user.email,
role: req.user.role,
image: req.user.image,
});
});
auth 라우터를 생성한다. 중간에 auth미들웨어가 있고 이것은 middlware 폴더안에 생성해준다. 미들웨어가 성공적으로 통과된 경우만 auth 라우터로 오기 때문에 성공을 보내준다.
미들웨어
// 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;
if (!user) return res.json({ isAuth: false, error: true });
// 유저를 찾은 경우, 요청에 user 정보를 넣어줌
req.token = token;
req.user = user;
next(); // 미들웨어 탈출
});
// 유저가 있으며 인증 확인, 없으면 nope!
};
module.exports = { auth };
auth 미들웨어에서 쿠키(클라이언트)에 저장된 토큰을 가져와 데이터베이스의 토큰과 비교한 뒤 맞는 유저라면 그때 유저 정보를 요청에 담아서 라우트로 보낸다(next). 없다면 인증 실패를 담음 정보를 보낸다. 아래는 요청에 유저 정보를 저장하는 부분만 따로 빼둔것이다.
(
req.token = token;
req.user = user;
// 이부분이 있기 때문에 auth 라우트에서 user와 관련된 정보를 사용할 수 있는것이다.
)
findByToken은 마찬가지로 user.js에서 정의해준다.
findByToken
...
userSchema.statics.findByToken = function (token, callback) {
let user = this;
// 토큰을 디코드
jwt.verify(token, 'secretToken', function (err, decoded) {
// 유저 아이디를 이용해서 유저를 찾은 다음
// 클라이언트에서 가져온 token과 db에 보관된 토큰이 일치하는지 확인
user.findOne({ _id: decoded, token: token }, function (err, user) {
if (err) return callback(err);
// 일치하는 유저를 콜백으로 전달
callback(null, user);
});
});
};
...
클라이언트에서 가져온 token을 이용해 id를 알아내고 얻어낸 id와 가져온 token과 같은 정보를 가진 유저를 찾는다.
auth 라우트의 기능은 후에 클라이언트와 연결했을 때 제대로활용된다. HOC, Higher Order Component를 만들어 거기에서 이 auth라우트로 요청을 보내 인증을 완료하고 페이지 별로 인증한 유저와 안한 유저를 구분하게 할 수 있다.