결과 확인을 위해서 db를 만들지 않고 id:root, pw:root를 기준으로 시작했다.
A. 토큰 생성 및 쿠키에 저장
1. login페이지에 와서 맞는 값을 입력했을때 미리 만들어둔 토큰 생성 미들웨어로 토큰을 생성한다.
토큰 생성은 2021.05.27 - [Lecture] - TOKEN 암호화 참고
2. 생성한 토큰을 옵션값과 함께 cookie에 저장해준다.
app.post('/auth/local/login',(req,res)=>{
let {userid,userpw} = req.body;
let result = {};
if(userid=='root' && userpw=='root'){
result = {
result:true,
msg:'login success'
}
let token = ctoken(userid);
res.cookie('AccessToken',token,{});
} else{
result={
result:false,
msg:'check your ID and PASSWORD'
}
}
res.json(result);
})
2-1. query로 받은 userid와 userpw 값이 같을때는 result를 true 값으로, 메세지로 login success 텍스트를 보내준다.
값이 틀릴때는 result를 false값으로, 메세지로는 아이디와 패스워드를 확인하라고 하고 그 result값을 담은 객체를 json형
식으로 응답보낸다.
let {userid,userpw} = req.body;
let result = {};
if(userid=='root' && userpw=='root'){
result = {
result:true,
msg:'login success'
}
} else{
result={
result:false,
msg:'check your ID and PASSWORD'
}
}
res.json(result);
2-2. ctoken(미리 만들어둔 function)을 사용해 토큰을 생성하고 그 값을 token이라는 변수로 저장해준다.
let token = ctoken(userid);
2-3. 마지막으로 응답 쿠키에 2-2에서 만든 token을 cookie에 AccessToken이라는 이름으로 저장했다.
res.cookie('AccessToken',token,{});
3. 결과값을 담은 후 메인 페이지로 이동한다.
B. 토큰 유효성 검사
user info를 클릭했을때:
1. 미들 웨어를 통해 cookie에 저장해둔 토큰값이 없을때 회원정보를 확인하지 못하도록 result값과 메세지를 보낸다.
app.get('/user/info',auth,(req,res)=>{
res.send(`HELLO ${req.userid}`)
});
1-1. A에서 저장했던 AccessToken을 쿠키에서 불러온다.
let {AccessToken} = req.cookies; // client의 cookie.accesstoken에서 가지고 와야한다.
if(AccessToken == undefined){
res.json({result:false,msg:'로그인을 진행해주세요'});
return
}
2. 토큰값을 .을 기준으로 split하고 각각의 변수에 저장해준다.
let [header,payload,sign] = AccessToken.split('.');
3. 현재의 토큰값과 처음 생성한 토큰 값이 같은지 (변화된게 없는지) 확인한다.
let signature = getSignature(header,payload);
function getSignature(header,payload){
const signature = crypto.createHmac('sha256',Buffer.from(process.env.salt))
.update(header+'.'+payload)
.digest('base64')
.replace('==','')
.replace('=','');
return signature;
}
4. 결과 값이 같다면 볼수 있고, 다르다면 볼 수 없게 처리 한다.
if(sign == signature){
next();
}else{
res.json({result:false,msg:'wrong Token'})
}
}
4-1. 토큰 값이 맞다면 payload를 다시 객체로 만들어서 그 안에 userid 값을 변수로 빼준다.
let {userid,exp} = JSON.parse(Buffer.from(payload,'base64').toString());
req.userid = userid;
5. 결과값이 같아도 토큰의 기간이 만료 되었다면 cookie에 저장된 토큰을 지우고 토큰이 만료되었다는 메세지를 보낸다. 이럴경우 로그인을 다시해서 새로운 토큰을 받아야 한다.
5-1. 미리 지정해둔 토큰의 만료시간과 현재 시간을 비교해서 만료기간을 넘었으면 쿠키에 저장되어있는 토큰을 삭제 후 메세지를 보낸다.
if(nextdate > exp){
res.clearCookie('AccessToken');
res.redirect('/?msg =your token is expired');
}
전체 코드
module.exports = (req,res,next)=>{
let {AccessToken} = req.cookies;
if(AccessToken == undefined){
res.json({result:false,msg:'로그인을 진행해주세요'});
return
}
let [header,payload,sign] = AccessToken.split('.');
let signature = getSignature(header,payload);
if(sign == signature){
let {userid,exp} = JSON.parse(Buffer.from(payload,'base64').toString())
let nextdate = new Date().getTime();
if(nextdate > exp){
res.clearCookie('AccessToken');
res.redirect('/?msg =your token is expired');
}
req.userid = userid;
next();
}else{
res.json({result:false,msg:'wrong Token'})
}
}
function getSignature(header,payload){
const signature = crypto.createHmac('sha256',Buffer.from(process.env.salt))
.update(header+'.'+payload)
.digest('base64')
.replace('==','')
.replace('=','');
return signature;
}

메인 페이지

로그인 페이지

로그인 실패

로그인 성공

회원 정보