IT/기타

[IT] 로그인 시 세션 관리 방법

땅일단 2024. 8. 4. 02:55

최근 프로젝트를 하면서 세션을 관리하는 방법에 대해 고찰해 봤다.

 

 

- JWT 이용 방법

토큰 기반 인증 방식이라고 불리는 방법을 JWT(Json Web Token)로 구현한 것이다.

0. 로그인 성공
1. 서버에 저장된 고유한 비밀키를 이용해 만료시간이 부여된 JWT 토큰을 발급한다.
2. 클라이언트로 토큰을 보내고, 브라우저에 토큰을 저장한다.
3. 요청 시마다 헤더에 토큰을 넣어서 보낸다.
4. 서버의 비밀키를 이용해 토큰이 유효한지 확인한다.

 

-> 장점 : DB 액세스 안해도 됨, 토큰에 사용자 이메일이나 권한 정보를 담을 수 있어서 편리함.
-> 단점 : 사용자를 강제로 로그아웃할 시킬 수가 없음. 이러한 개입이 필요한 사례는 보안 위협이 생겼을 경우(토큰 탈취 등), 패스워드가 변경되었을 때처럼 모든 곳에서 사용자를 로그아웃 시켜야 할 일이 있을 경우 등이 있음.

 

 

- JWT (토큰 2개) 이용 방법

0. 로그인 성공
1. 비밀키로 JWT 토큰을 발급하는데 Access Token, Refresh Token 이렇게 2개 발급한다.
2. 액세스 토큰은 만료시간이 짧고(30분~1일 정도), 리프레시 토큰은 길다(일주일~1개월 정도).
3. 요청 시마다 액세스 토큰을 넣어서 보낸다.
4. 액세스 토큰이 만료되면 리프레시 토큰을 요청하여 새로운 액세스 토큰을 응답받는다. (로그인 상태는 유지)
5. 리프레시 토큰도 만료되었거나 유효하지 않으면 로그아웃 상태가 된다.

 

-> 장점 : 액세스 토큰은 보통 브라우저 측 저장소에 저장하니 관리가 편리하고, 리프레시 토큰은 보통 httpOnly 쿠키 등으로 서버측에 숨겨놓으니 편의성과 보안에 좋다. 액세스 토큰이 탈취당하더라도 만료시간이 짧아서 피해가 적음.
-> 단점 : 혹시나 만료기간이 긴 리프레시 토큰이 탈취되면 피해가 큼.

 

 

- Redis 등의 Key-Value형 NoSQL 이용 방법

세션 기반 인증 방식이라고 불리는 방법을 DB를 통해 구현한 것이다.

0. 로그인 성공
1. Redis에 key를 계정아이디로, value를 uuid로 하고 만료시간을 부여한 후 insert한다.
2. 클라이언트로 uuid를 보내고, 브라우저에 uuid를 저장한다.
3. 요청 시마다 헤더에 uuid를 넣어서 보낸다.
4. uuid를 Redis와 대조하여 유효한지 확인한다.

 

-> 장점 : 보안 위협이 생길 경우 사용자를 강제로 로그아웃시킬 수 있음

-> 단점 : DB에 액세스해야 함

 

 

 

토큰 / uuid는 어디에 저장할까?

 

 

- 로컬 스토리지나 그냥 쿠키에 저장

-> 프론트에서 관리할 수 있어서 편의성 면에서 좋음

-> 브라우저측 저장소에 uuid를 저장하므로 XSS 공격에는 취약함 (탈취 가능성)

-> 최신 프론트엔드 프레임워크들은 XSS를 어느정도 방어해주긴 함

 

- httpOnly 쿠키에 저장

-> 자바스크립트 코드로 쿠키에 접근할 수가 없어서 XSS에 안전함

-> 프론트에서 접근을 못하므로 서버에서만 관리가 가능함 (발급, 조회, 삭제 등)

-> secure 설정까지 해 주면 https 요청에만 쿠키가 포함되므로 더욱 안전함

 

 

(+) ssl을 사용한다면 가능성은 적겠지만 혹시라도 토큰 / uuid가 탈취당하면 만료시간 전까지 CSRF 공격이 가능하기에 같은 도메인에서의 요청만 받도록 서버측에서 CORS 설정을 해 주는 게 좋음