관리 메뉴

SIMPLE & UNIQUE

USER 정보 로그인 세션관리/react-cookies/jsonwebtoken 본문

React & Node/Guide

USER 정보 로그인 세션관리/react-cookies/jsonwebtoken

착한코딩 2019. 11. 5. 11:17

이전 회사에서는 Spring 프레임 워크에서 서버 Session에 로그인 정보를 세팅하여 사용했다.

보통 javax.servlet.http 패키지의 HttpSession 인터페이스를 구현해서 사용한다.

session.setAttribute("id", "value");//세션 setting
session.getAttribute("id");//세션 read
session.removeAttribute("id");//세션 remove

서버 session을 사용하는 것이 cookie를 사용하는 것보다 보안측면에서 강력하다.(브라우저상에 노출되지 않는다.)

node/react 서버에서는 방어로직을 함께 구현하여 cookie를 사용하였다.

구현 방식은 아래와 같다.

 

1. 로그인

 1-1) 입력받은 id/pw를 DB값과 비교해서 일치하는 회원정보가 있다면, 로그인처리를 한다.
        DB에서 userid, username, 암호화된 password를 호출해서  react 서버로 가져온다.

...
axios.post('/api/LoginForm?type=signin', {
	is_Email: this.email_val,
	is_Password: this.pwd_val
})
...
var userid = response.data.json[0].useremail
var username = response.data.json[0].username
var userflag = response.data.json[0].userflag
var upw = response.data.json[0].userpassword
...

 1-2) password그대로 쿠키에 넣고, useridusername인코딩+서명(비밀키 암호화)을 하기 위해 node server로 보낸다.

=> httpOnly 옵션을 주면 사이트 외부에서 쿠키값에 접근하는 것을 막을 수 있다.(탈취방지)

...
axios.post('/api/LoginForm?type=SessionState', {
	is_Email: userid,
	is_UserName: username,
})
.then( response => {
...
cookie.save('userid', response.data.token1
, {
	path: '/',
	expires,
	httpOnly: true
})

cookie.save('username', response.data.token2
, {
	path: '/',
	expires,
	httpOnly: true
})

cookie.save('userpassword', upw
, {
	path: '/',
	expires,
	httpOnly: true
})

}) 
...

 1-3) node server에서는 jwt토큰을 만든다.

//jwt.js 파일
let jwtObj = {};

jwtObj.secret = "appfsdfsdfle"

module.exports = jwtObj
let jwt = require("jsonwebtoken");
let secretObj = require("../ignorefile/jwt");
...
let token1 = jwt.sign({
	email: userid   // 토큰의 내용(payload)
},
	secretObj.secret ,    // 비밀 키
{
	expiresIn: '60m'    // 유효 시간은 60분
})
...

res.send({"token1":token1, "token2":token2});

여기서 '내용' 부분에 userid 값이 들어가는데, 이 부분은 단순 인코딩만 한다.
핵심은 서명인데, 로그인 인증이 필요한 시점에 쿠키값을 불러오고

이때 토큰 뒤에 붙은 서명로그인 처리시에 발행한 서명과 다르다면 로그인 처리를 하지 않는다.

=> 사용자정보를 아는 누군가 쿠키를 조작하더라도, 서명을 통해 걸러낼 수 있다.(조작방지)

 

2. 사용자 인증

 2-1) 사용자 인증시 쿠키값에 있는 userid, usernm정보를 가지고, 토큰값의 서명이 해당 사이트에서 발행한 것이 맞는지 확인한다.

//react 코드
axios.post('/api/LoginForm?type=SessionConfirm', {
 token1 : cookie.load('userid') 
 , token2 : cookie.load('username') 
})
//node코드
...
let token1 = req.body.token1;
...
let decoded1 = jwt.verify(token1, secretObj.secret);
...
res.send({"token1":decoded1.email, "token2":decoded2.username});
...

 2-2) 사이트에서 발행한 서명이 맞다면, 사용자 정보 DB에 접속해 유효한 사용자인지 체크한다.

 2-3) 쿠키값이 없거나, 일치하는 사용자 정보가 없거나, 서명이 일치하지 않거나, DB호출 중 오류가 발생한다면

       모든 쿠키값을 삭제하고 로그인 화면으로 이동시킨다.

Comments