Node.js

node>회원기능 (JWT, session, OAuth 설명시간)

연습노트 2024. 7. 25. 19:24

회원기능 동작방식 

 

예를 들어 게시물들을 로그인한 사람만 볼 수 있게 만든다고 칩시다. 

그럼 회원기능이 필요한데 어떤 식으로 회원기능을 만들면 되냐면

 

회원가입 : 

1. 유저가 가입하면 아이디/비번을 DB에 저장해둠 

 

로그인 : 

1. 유저가 로그인시 아이디/비번을 서버로 보냄 

2. 서버는 DB에 있는 아이디/비번과 유저가 보낸 아이디/비번이 일치하는 경우 입장권을 발급해줌 

 

로그인이 필요한 서버기능 : 

1. 유저는 서버에 GET/POST로 데이터 요청시 입장권도 함께 제시함 

2. 서버는 입장권 확인 후 데이터나 페이지 보내줌 

이런거 만들어두면 회원기능 끝입니다.

 

아이디/비번 이런거 DB에 저장하는건 여러분도 할 수 있으니까 패스하고

오늘은 입장권을 어떤 식으로 만드는지 알아봅시다. 

 

 

 

 

 

입장권이 뭐냐면 

 

입장권은 그냥 유저 정보가 써있는 간단한 문자자료입니다. 

로그인완료시 서버가 "이 사람은 누구고 언제 로그인했습니다" 이런 문자를 대충 만들고

유저에게 보내서 사용하게 만들면 그것이 입장권일 뿐입니다. 별거 아님 

 

 

▲ 그냥 이렇게 생겼습니다.

 

Q. 저는 평생 인터넷서핑하면서 입장권을 본 적이 없는데요?

- 일반 유저들에게 입장권을 직접 사용하게 만들면 귀찮아하기 때문에 

유저 모르게 입장권을 제시하게 만들 수 있는 방법이 있습니다. 

브라우저의 쿠키 저장소를 이용하면 됩니다. 

비유가 아니라 크롬 개발자도구 켜면 진짜로 Application 탭에 Cookie라고 있습니다. 

 

쿠키 저장소에 저장해놓은 쿠키는 서버로 GET/POST 요청시 자동으로 함께 전송됩니다.

그래서 서버는 유저의 브라우저의 쿠키라는 공간에 입장권을 강제로 저장시켜둡니다.

(서버는 그런 권한이 있음)

 

그래서 아무튼 로그인시 입장권 만들어서 유저 브라우저 쿠키에 넣어두면 되는데

입장권을 만들 때 대표적으로 session, token 방식 2개가 있는데 택1 하면 됩니다.

 

 

 

 

 

 

session 방식

 

session 방식을 쓴다면

 

 

로그인 : 

1. 유저가 로그인하면

DB에 { 유저의 아이디, 로그인 날짜, 유효기간, session id } 이런걸 기록해두고 

2. 유저에게 입장권을 발급해줄 때 입장권에 session id 하나만 달랑 적어보냅니다.

 

로그인이 필요한 서버기능 :

1. 유저가 GET/POST 요청시 입장권을 서버에 제출함 

2. 서버는 입장권에 써있는 session id를 가지고 DB를 조회해본 다음 

DB기록에 별 이상 없으면 GET/POST요청을 진행시켜 줍니다. 

 

장점은 매번 GET/POST 요청할 때 마다 DB를 조회해보기 때문에

하나하나의 요청마다 엄격하게 유저를 체크해볼 수 있습니다. 

단점은 그 만큼 DB의 부담이 심해질 수 있습니다.

그래서 유저가 많은 사이트들은 조금 더 빠른 Redis 같은 DB를 사용하기도 합니다.

 

 

 

 

 

token 방식

 

대부분 JWT라고 불러서 그냥 JWT라고 하겠습니다. JSON Web Token의 약자임 

JWT방식을 쓴다면

 

 

로그인 : 

1. 유저가 로그인하면

유저에게 입장권을 발급해줄 때 입장권에 { 유저의 아이디, 로그인 날짜, 유효기간 } 등을 적어두고 암호화해서 보냅니다.

DB에 뭐 저장하는건 없음 

 

로그인이 필요한 서버기능 :

1. 유저가 GET/POST 요청시

유저가 입장권을 제출하면 { 유저의 아이디, 로그인 날짜, 유효기간 } 이 적혀있는데 

그거 까보고 유효기간에 별 이상 없으면 통과시켜 줍니다.

유저 정보가 필요하면 입장권에 써있는거 꺼내서 씁니다.

 

 

Q. 유저가 JWT를 맘대로 위조하면 어쩌죠?

근데 JWT를 만들 때 여러 정보들을 짧은 문자로 변환을 해서 만드는데 (일명 hashing)

변환할 때 암호를 넣을 수 있어서 암호가 변경되거나 내용이 변경되면 짧은 문자도 변하기 때문에

위조여부를 쉽게 알 수 있어서 걱정은 안해도 됩니다. 

 

JWT의 장점은 매번 GET/POST 요청할 때 마다 DB를 조회할 필요가 없어서 DB 부담이 적습니다.

그래서 유저가 매우 많거나 마이크로서비스형태로 서버를 많이 운영하는 사이트들이 즐겨쓰는 경향이 있습니다. 

 

단점은 유저의 JWT를 나쁜 사람이 훔쳐가면 그 사람의 로그인을 막거나 할 수 있는 방법이 없습니다. 

그리고 다른 컴퓨터에 저장된 JWT를 소멸시키거나 그럴 수는 없기 때문에 다른 컴퓨터를 로그아웃시키기도 어려울 수 있습니다.

 

물론 나쁜 JWT들을 모아서 DB 같은 곳에 기록해두면 되는데

그러면 매번 JWT 사용마다 DB를 조회해야하니 session 방식과 딱히 다른 점이 없음 

아무튼 session, JWT 각각 장단점이 있으니 골라서 사용하도록 합시다. 

 

 

 

 

 

 

번외 : OAuth

 

OAuth는 입장권같은건 아니고 OAuth의 뜻은 

어떤 유저의 A 사이트의 사용권한을

B 사이트를 운영하는 내가 잠깐 빌릴 수 있는데

그 과정을 정의하는 규칙같은겁니다. 

 

그래서 OAuth를 잘 이용하면 유저의 A 사이트 회원정보를 가져와서 내가 운영하는 B 사이트 회원가입시 사용할 수도 있고

이걸 흔히 소셜로그인이라고도 부릅니다. 

 

 

 

예를 들어 코딩애플이라는 사이트를 운영하는데 구글로그인을 구현하고 싶으면 어떤 식으로 이루어지냐면 

1. 유저가 코딩애플 사이트에서 구글 로그인 버튼을 누르면 구글 계정으로 로그인하라고 뜨는데 로그인합니다. 

2. "수상한 코딩애플 사이트로 느그 개인정보 전송해도 되냐"고 구글이 물어봅니다.

3. 유저가 허락하면 허락했다고 구글 -> 코딩애플서버 이렇게 알림을 전송합니다. 

4. 알림이 도착하면 코딩애플서버는 구글에게 유저 정보를 요청해서 받아옵니다.

거기엔 { 유저이메일, 이름, access_token, 유효기간 } 이런 것들이 들어있습니다.

 

그 정보들로 JWT 만들어서 사용하거나 session 으로 DB에 저장해두거나 마음대로 한 다음 

코딩애플 사이트 로그인기능 구현시 사용하면 됩니다. 

 

 

 

 

 

 

passport 라이브러리

 

Node.js 환경에서 로그인 기능 구현시

직접 코드짜기 귀찮기 때문에 passport 라이브러리를 써봅시다. 

이거 쓰면 session, jwt, OAuth 중 원하는 방식 자유롭게 사용할 수 있으며 

특히 사용자가 많아서 초보자들이 참고할 예제도 인터넷에 많습니다.