해시함수(항상 같은 길이의 문자열 리턴, 서로 다른 문자열에 동일한 해시 함수를 사용 시 반드시 다른 결과값, 동일한 문자열에 동일한 해시함수 사용 시 항상 같은 결과값)를 사용하여 암호화를 진행하는 방식이다. 해시함수는 레인보우 테이블를 이용하여 이전의 값을 알아낼 수 있도록 한다. 레인보우 테이블을 때문에 데이터 유출 가능성이 있어 보안상 위협이 될 수 있다. 이때, 솔트라는 임의 값을 더하여 해싱 이전의 값을 알아내기 힘들게 많드는 방법을 사용한다.
해시함수는 레인보울 테이블과 솔트를 이용하여 불가역(단방향)한 성질을 가지는데, 바로 해싱의 목적이 동일한 데이터읹 아닌지에 대한 여부만 확인하는 것이기 때문에 복호화가 불가능한 암호화방식을 사용한다.
✅ 인증과 권한 정보를 담고 있는 암호화된 문자열로 사용자에게 접근 권한을 부여할 수 있다.
장점 | 단점 |
---|---|
① 무상태성 : 서버가 유저의 인증 상태를 관리하지 않고 비밀키를 통해 토큰의 유효 검증만 하기 때문에 | ① 무상태성 : 서버가 인증상태를 관리하는 주체가 아니라, 토큰이 탈취되면 강제로 만료 시킬 수 없다 |
② 확장성 : 다수의 서버가 공통된 세션 데이터를 가질 필요가 없기 때문에 | ② 유효기간 : 탈취 상황을 대비해 유효기간을 짧게 설정하면 로그인을 매번해야 해서 사용자 경험 감소, 길게 설정하면 탈취 시 위험 |
③ 어디서나 토큰 생성 가능 : 토큰의 생성과 검증이 꼭 하나의 서버에서 이루어질 필요가 없기 때문에 | ③ 토큰의 크기 : 많은 데이터를 담으면 암호화 과정도 길어지고 토큰의 크기도 커져 네트워크 비용문제 발생 |
④ 권한 부여에 용이 : 토큰에 인증상태나 접근 권한 등의 다양한 정보를 담을 수 있기 때문에 |
✅ 액세스 토큰 : 사용자가 서버 리소스에 접근할 수 있도록 접근 권한을 제공하는 토큰으로 보안을 위해 만료 주기가 짧다.
✅ 리프레시 토큰 : 토큰의 짧은 만료 주기로 인해 사용자 경험 하락을 막기 위해 고안된 토큰으로 기존에 발급받은 액세스 토큰이 만료되었을 때 액세스 토큰을 얻기 위해 사용한다.
리프레시 토큰이 모든 문제를 해결하지는 않지만 액세스토큰보다는 긴 유효기간을 가지고 있기 때문에 이 토큰 마저 탈취 당할 수 있다.
사용자가 ID, PW를 통해 로그인
서버에서는 회원 DB에서 값을 비교한다.(보통 PW는 일반적으로 암호화해서 들어간다.)
사용자 인증이 되면 서버에서 Access Token, Refresh Token을 발급, 보통 회원 DB에 Refresh Token을 저장해준다.
서버는 사용자에게 Access Token, Refresh Token 을 보낸다.
사용자는 Refresh Tokendms 은 안전한 저장소에 저장 후, Access Token을 헤더에 실어 요청을 보낸다.
서버는 Access Token을 검증하고 로그인 성공 신호를 보낸다.
로그인 성공 신호에 맞는 데이터를 사용자에게 보내준다.
~ 시간이 흘러 Access Tokendl 만료 ~
사용자는 만료된 Access Token을 헤더에 실어 요청을 보낸다.
서버는 Access Token이 만료된을 확인한다.
만료된 토큰임을 알리고 권한없음을 신호로 보낸다. Access Token이 만료될때 마다 9~11 과정을 거칠 필요는 없다. Access Token의 Payload를 통해 유효기간을 알수 있다. 따라서 프론트엔드 단에서 API 요청 전에 토큰이 만료 됐다면 바로 재발급 요청 가능.
사용자는 Refresh Token과 Access Token을 함께 서버로 보낸다.
서버는 받은 Access Token이 조작되지 않았는지 확인한후, Refresh Token과 사용자의 DB에 저장되어 있던 Refresh Token을 비교한다.
서버는 Token이 동일하고 유효기간도 지나지 않았다면 새로운 Access Token을 사용자에게 보내준다. 새로운 Access Token을 헤더에 실어 API 요청을 한다.
- 입력한 정보(아이디와 패스워드)가 DB 정보와 일치하는 경우 클라이언트에게 로그인 성공에 대한 응답 전송 + 쿠키에 JWT 담아 전송 ( 302 , /userInfo 로 리다이렉트 )
- 로그인 유지 체크시 -> access token & refresh token(영속성 쿠키)
- 로그인 유지 노 체크시 -> access token(세션 쿠키)
- 일치하지 않는 경우 로그인 실패에 대한 응답 전송 ( 401 , Not Authorized )
토큰 검증
1. access token 검증이 성공하면 payload 를 통해 DB 에 유저 정보를 조회
1-1. 조회가 된다면 로그인 성공에 대한 응답 + 비밀번호를 삭제하고 유저 정보 전송
1-2. 조회가 되지 않는다면 로그인 실패에 대한 응답 전송 ( 401, Not Authorized )
2. access token 검증이 실패(=만료)되었다면 refresh toekn 검증하기
2-1. refresh token 검증이 실패하면 로그인 실패에 대한 응답 전송 ( 401, Not Authorized )
2-2. 검증 성공하면 DB 에 유저 정보를 조회
2-3. 조회 된다면 access token 재발급 + 쿠키에 JWT 다시 담아 전송 ( /userInfo 로 리다이렉트 )
2-4. 조회 되지 않는다면 로그인 실패에 대한 응답 전송 ( 401, Not Authorized )
3. access token, refresh token 검증 실패시 로그인 실패에 대한 응답 전송 ( 401, Not Authorized )
쿠키 삭제 ➡️ 기본적으로 access token 삭제, refresh token 존재한다면 이것도 삭제