본문 바로가기

코딩애플/코딩애플-node

세션, JWT, OAuth 등 회원인증 방법론

Types of Authentication

 

 

 

1. session-based 회원인증방법

웹페이지에서 로그인을 성공하면

서버에서 세션을 만들어서 쿠키에 세션아이디를 담아 웹페이지로 전송한다

브라우저는 세션값을 쿠키로 저장한다.

세션값을 서버와 브라우저가 공유한다.

 

session-based 회원인증방법은

사용자의 세션정보를 저장해서 로그인 기능을 구현하는 방법입니다.

 

- 이 사람이 로그인 했었다는 정보를 서버의 메모리에다가 기록해놓습니다. (세션을 저장합니다.)

- 그리고 고객이 로그인이 필요한 페이지(Mypage 등)를 요청을 하면 

- 세션을 들춰봐서 이 사람이 로그인했다는 정보가 나오면 통과시켜줌~!

 

 

어떤 사람이 로그인하면 세션아이디를 하나 발급해서 서버와 고객이 나눠가집니다.

그리고 고객이 마이페이지같은거 요청할 때마다 "니 세션아이디 뭔데" 라고 물어보면 됩니다. 

 

세션은 매우 전통적이고 범용적으로 사용되는 인증방식입니다. 

그러므로 여러분이 개발 중 위기에 처했을 때 참고할 구글 검색결과가 풍부합니다. 

 

 

 

 

1. 서버에서 세션을 만든다

1) 로그인시 제출한 아이디, 비번이 DB 저장된 회원정보와 맞다면 

서버는 옳다구나 하고 세션스토어에 세션 하나를 만들어서 저장합니다. 

세션은 용어가 어려워서 그렇지 그냥 이 사람이 언제 어디서 로그인 했는지 이런 정보를 담은 자료라고 보시면 됩니다.

"Kim 이라는 사람이 7시에 로그인했습니다."

뭐 이런 정보를 서버 메모리에 저장해둡니다. 

 

2) 그리고 로그인한 유저마다 각각 유니크한 세션아이디라는걸 발급합니다. 

당연히 로그인한 사람이 여러명일 수 있으니 유니크한 세션아이디를 발급해서 구분지어주는게 좋겠죠.

그래서 abc123 이라고 세션아이디를 하나 예쁘게 발급해줬습니다. 

 

 

2. 서버에 있는 세션정보를 쿠키에 담아서 브라우저에게 전달한다.

2. 발급한 세션아이디는 쿠키에 담아서 고객 브라우저에 전송해줍니다. 

세션아이디는 고객과 서버 둘다 보관합니다. 그래서 쿠키에 담아서 고객에게 보내줍니다.

* 쿠키란 브라우저에 마련되어있는 쪼그만한 문자데이터 저장공간입니다. 여기에 세션아이디가 abc123 이렇게 기록됩니다. 

 

 

3. 브라우저는 쿠키에 있는 세션값을 저장한다.

브라우저에는 쿠키로 정보를 저장한다.

쿠키는 브라우저에 저장 할 수 있는 긴 문자열이다.

 

4. 브라우저는 세션값으로 서버에게 마이페이지를 요청한다

4. 고객이 마이페이지를 요청합니다. 

/mypage를 달라고 요청하면 서버는 응답.render() 해주기 전 일단 가로막습니다. 

"님 로그인 했었음?" 이라고 물어봐야하니까요.

물어보는 과정은 심플합니다. 

5. 서버는 세션값을 확인하여 일치하는지 확인한다

5. 쿠키에 세션아이디가 포함되어있는지 검사합니다. 

원래 고객이 페이지를 요청할 때 마다 자동으로 쿠키가 서버로 전송됩니다.

그럼 서버는 쿠키에 기록된 세션아이디를 서버메모리 or DB에 저장되어있던 세션아이디와 비교해서

있으면 통과시켜줍니다. 

 

 

6. 서버는 브라우저에게 마이페이지를 전달한다.

6. 서버는 마이페이지를 보내줍니다. 

그 전에 이 회원의 이름, 나이, 성별 등의 DB 정보가 필요하다면

세션데이터를 참고해서 이 사람의 이름, 나이 등의 정보를 DB에서 꺼내옵니다. 

끝입니다. 

 

 

 

 

 

2. token-based(jwt)

토큰 방식은 세션데이터를 서버에 저장하지 않고

마이페이지를 열람할 수 있는 열쇠(토큰)를 사용자에게 쥐어주는 것입니다. 

그래서 그 열쇠에는 session방식보다 약간 더 많은 정보들이 들어갑니다. 

요즘 토큰토큰 거리면 JSON Web Token을 말하는 것인데, 아무튼 어떤 방식인지 자세히 알아보도록 합시다. 

 

 

 

1. 브라우저에서 로그인이 성공하면 서버는 TOKEN을 브라우저로 전송한다. 토큰은 브라우저의 쿠키 또는 로컬스토리지에 저장된다.

 

1. 로그인시 제출한 아이디, 비번이 DB 저장된 회원정보와 맞다면 

서버는 옳다구나 하고 Token 하나를 만들어서 고객 브라우저로 보내줍니다. 

Token은 그냥 긴 암호화된 문자열일 뿐이고,

사용자가 로그인 했었는지, 아이디는 무엇인지 이런 정보들을 넣을 수 있습니다. 

물론 위조가 불가능하도록 특별한 서명이 추가됩니다. 

토큰은 쿠키나 로컬스토리지라는 곳에 저장됩니다. 

(+ 코드를 잘 짜서 고객이 페이지 방문시마다 Token이 서버로 보내지도록 미리 장치를 추가합니다. )

 

 

 

 

2. 브라우저는 토큰값과 마이페이지 요청을 서버에게 보낸다.

2. 고객이 마이페이지를 요청하면  

브라우저가 /mypage를 달라고 요청하면

서버는 응답.render() 해주기 전 일단 가로막습니다. 

 

"님 로그인 했었음?" 이라고 물어봐야하니까요.

물어보는 과정은 그냥 토큰 검사입니다. 

 

 

 

3. 서버는 토큰을 검사합니다

고객이 마이페이지 요청시 함께 보낸 Token이 적법한지 검사합니다. 

유통기한이 지나지 않았는지, 서명이 잘 되어있는지, 블랙리스트에 등록된 토큰인지 이런 검사를 거친 후

이상이 없으면 마이페이지로 통과시켜줍니다. 

 

 

 

 

세션은 로그인 상태를 저장합니다.

토큰의 유통기한이 지나지 않았는지, 서명이 잘 되어있는지, 블랙리스트에 등록된 토큰인지를 가지고 있다.

세션은 토큰보다 더 적은 정보를 가집니다.

 

 

기본적인 토큰 구현은 매우 간단합니다.

그리고 서버는 세션데이터 등을 메모리/DB에 저장해둘 필요가 없으니 나중에 서버 스케일링시 큰 문제가 없다는 장점도 있습니다. 

 

 

 

하지만 단점이나 보안상 취약점이 존재할 수 있습니다.

이 사람이 로그인 했는지에 대한 정보 전체를 서버는 가지고 있지 않고 사용자가 가지고 있게 하는 것 자체가 보안상 좋은 방법은 아닙니다.

JWT 정보를 다른 사람이 훔치면 어쩔 것임? 이제 훔친 사람은 자유롭게 로그인이 가능하겠는데요? 

그래서 stateful JWT 라고 부르는 '어떤 사람이 언제 로그인했는지'를 서버에 저장해두는 방식이 좋은 관습이긴 한데

그 중 하나가 refresh token 이런 방식입니다.  

그러면 위에서 말했던 세션 방식이랑 기능 상 다를바가 없습니다. 

 

 

 

3. Open Authentication (OAuth)

이 방법은 쉽게말하면 페이스북, 구글 로그인입니다.

고객의 페이스북, 구글 계정정보를 불러와서 그걸 가지고 가입을 승인시켜주는 방법입니다.  

 

 

 

 

1. 어떤 사람이 '페이스북으로 로그인' 버튼을 눌렀다고 칩시다.

그럼 페이스북 팝업이 뜹니다. 

"코딩애플 앱에 본인의 페이스북 이름, 아이디 제공을 승인하시겠습니까?"

승인을 눌러봅니다. 

 

 

 

 

 

2. 그럼 페이스북은 우리 server.js에게 이 유저의 이름, 아이디 정보를 보내줍니다. 

그럼 뭘 해야할까요. 여러분이 하고싶은거 하시면 됩니다.

 

3. 이 사람 페이스북 정보를 바탕으로 세션이나 토큰을 만들어줍니다. 

DB에 이름, 아이디를 저장해서 회원 목록을 하나 만들어주든가,

그와 동시에 세션 데이터를 만들어주든가 하시면 됩니다. 

server.js에 코드를 잘 짜서 하면 되겠죠.

 

4. 고객이 마이페이지를 요청하면  

/mypage를 달라고 요청하면 서버는 응답.render() 해주기 전 일단 가로막습니다. 

"님 로그인 했었음?" 이라고 물어봐야하니까요.

 

5. 서버는 토큰이나 세션을 검사합니다

위에서 세션을 만들어 줬다면 세션이 있는지 검사하면 되고,

위에서 토큰을 만들어 줬다면 토큰이 적법한지 검사하면 되겠죠?

통과되면 마이페이지를 응답.render() 해줍니다.