이번에는 사용자 기능을 추가한다!🌷
로그인이 되어 있는지, 관리자인지 확인하기 위해 인증 기능을 추가한다.
또한, 글을 수정하거나 삭제할 경우 권한이 있는지 확인한다.
index.js 에 auth router를 생성한다.
중간에 auth라는 미들웨어를 만들고 중간에서 인증을 처리할 것이다.
// 현재 사용자와 일치하는 지 확인하고 권한을 부여
// auth 라는 미들웨어로 중간에서 인증 처리
app.get('/api/user/auth',auth,(req,res)=>{})
시스템의 구조는 사진과 같다.
클라이언트에서 토큰을 decode 해서 server에 보낸다.
user.id의 데이터 베이스에 가지고 있는 token이 client 에 있다면 인증을 성공한다.
만약 없거나 다르면 user가 다르기 때문에 인증에 실패한다.
- Cookie에 저장된 token을 server에서 가져와서 복호화를 한다.
- 복호화를 하면 user ID가 나온다.
- User ID를 이용해서 데이터 베이스 User Collection 에서 User를 찾는다.
- User를 찾은 후 쿠키에서 받아온 token이 유저도 갖고 있는지 확인한다.
4.1 쿠키가 일치하지 않으면 Autentication Fail!!!
4.2 쿠키가 일치하면 Autentication Success!!!- 인증에 성공하면 해당하는 유저의 정보를 선별해서 프론트앤드로 보내준다.
middleware 폴더를 생성하고 auth.js 파일을 추가한다.
클라이언트 쿠키에서 토큰을 가져와야 한다.
cookie parser를 이용한다.
let token = req.cookies.x_auth
우선 User.js 에서 토큰을 복호화하고 유저를 찾는 메서드를 만들어야 한다.
User.js 파일에서 findByToken를 생성한다.
토큰을 jwt.verify를 이용해서 복호화한다.
decoded 된 결과로 user.id를 확인할 수 있다.
user ID로 유저를 찾는다.
유저가 있으면 callback 함수로 user 정보를 보낸다.
userSchema.statics.findByToken = function(token, callback){
let user = this
// 토큰을 복호화
jwt.verify(token,'secretToken',function(err,decoded){
//user id 를 이용해서 유저를 찾은 다음에
// 클라이언트에서 가져온 토큰과 DB에 저장된 토큰과 일치하는 지 확인
user.findOne({"_id":decoded,"token":token},function(err,user){
if(err) return callback(err)
callback(null,user)
})
})
}
auth.js 파일에서 findByToken의 결과로 user 정보를 받아온다.
user 정보를 갱신하고 미들웨어에서 넘어간다.
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()
})
const {User} = require('../models/User')
let auth = (req,res,next)=>{
// 인증 처리를 하는 것
// 1. 클라이언트 쿠키에서 토큰 가져오기 => cookie parser 이용
let token = req.cookies.x_auth
// 2. 토큰을 복호화 한 후 유저를 찾기
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}
auth router에서 auth middleware를 통과한 건 인증을 성공했다는 의미이다!
프론트앤드에 user 정보를 전송한다.
app.get('/api/user/auth',auth,(req,res)=>{
// middleware를 통과했다.
// === Authentication 이 True
// role === 0 : 일반 유저
// role === 1 : 관리자
// role === 2 : 특정 부서 관리자
res.status(200).json({
_id:req.user._id,
isAdmin:req.user.role === 0 ? false : true,
isAuth: true,
email:req.email,
name: req.name,
lastname:req.lastname,
role:req.role,
image:req.image
})
})