로그인 인증 방식
로그인
- 웹서버는 원래 로그인이라는 기능이 없다.
- HTTP 프로토콜은 stateless 이다. 즉 연결성이 없다. 다시 요청을 할려면 다시 연결해야 한다. 즉 로그인 인증을 계속 해줘야한다.
인증 방식을 사용하는 이유
- 로그인을 하고 다음페이지로 이동할 때 또 로그인을 해야하는 사이트는 아주 불편할 것이다. 이러한 불편함을 없애고 사용자가 사이트 서비스를 편하게 이용하기 위해 인증 방식을 사용한다.
쿠키 인증 방식
- 로그인 인증을 성공하면 쿠키에 인증정보를 저장한다.
-
이러한 쿠키와 함께 서버에 요청을 하면 로그인 인증할 필요없이 빠르게 서버와 상호작용이 가능하다.
- 하지만 공격자가 쿠키변조 공격을 이용하여 로그인을 할 수있는 취약점이 있다. 즉 쿠키를 위조하면 공격자가 쉽게 로그인이 가능하다. 따라서 쿠키를 이용해서 로그인을 하는 것을 하면 안된다.
서버기반 인증
Session 방식
- 유저의 정보를 서버에 저장한다.
- 서버에 인증정보를 브라우저가 아닌 서버 측에 저장하고 관리한다.
- 클라이언트의 인증 상태정보를 저장한다.
인증과정
- 로그인에 성공하면 서버에서 session id 를 만든다. 그리고 이 session id를 쿠키에 담아 사용자에게 보낸다.
Session ID 를 통한 요청 과정
- 서버에서 받은 session id와 요청을 서버에 보내면 서버는 session id를 이용하여 유저 정보를 획득한다.
- 장점
- 각각의 사용자는 고유의 session id 를 발급받기 때문에 일일이 회원정보를 확인할 필요가 없다.
- 강제 로그아웃, 접속 인원 제한, 로그인 된 모든 디바이스를 서버에서 쉽게 확인이 가능하다.
- 단점
- 사용자 수가 늘어나면 session 저장소에 과부화가 걸린다.
- 서버에서 세션 저장소를 위한 추가적인 저장공간이 필요하다.
- 확장성이 띄어나지 않다. 서버가 늘어나면 세션 저장소를 외부로 분리하는 작업을 해야한다. 외부로 안보내면 세션 불일치 문제를 겪는다.
- 제 3자가 session id 가 들어있는 쿠키를 탈취한 후 이 쿠키를 이용해 HTTP 요청을 보내면 서버는 사용자를 오인해 정보를 전달하게 된다.(하이재킹 공격)
- 하이재킹 공격 예방
- HTTPS 프로토콜 사용 & Session 만료시간 추가 로 어느정도 예방할 수 있다.
- 서버 측에서 세션을 무효 처리 하면 된다.
Token 기반 인증
- 유저의 정보를 서버에 저장하지 않는다.
JWT (JSON Web Token)
- Access Token 으로 사용된다.
- 필요한 정보들을 암호화 시킨 토큰을 말한다.
- header, payload 그리고 verifiy signature 로 이루어져 있다.
- JSON Web Tokens - jwt.io
Header
- 토큰의 타입을 나타내는 typ와 암호화할 방식을 정하는 alg으로 구성되어있다.
alg
에는 여러가지 공개키 암호화 방식중 하나의 알고리즘을 적어주면된다. (HS256, HS512, PS256 등)- 디코딩어 있다.
{ 'alg': 'HS256', 'typ': 'JWT' }
Payload
- 토큰에 담을 정보들이 포함된다.
- 담는 정보의 한 조각을 클레임이라 한다.
- 노출되기 쉬움으로 민감한 정보를 담아서는 안된다. 왜냐하면 인코딩만 되어있기 때문에 쉽게 디코딩이 가능하기 때문이다. 암호화가 걸려있는 것이 아니다.
- 식별 하기 위한 정보를 담아두어야 한다.
- 여러개의 클레임을 넣을 수 있다.
- iss (Issuer) : 토큰 발급자
- sub (Subject) : 토큰 제목, 토큰에서 사용자에 대한 식별값이 됨
- aud(Audience) : 토큰 대상자
- exp (Expiration Time) : 토큰 만료 시간
- nbf (Not Before) : 토큰 활성 날짜
- iat (Issued At) : 토큰 발급 시간
- ti (JWT Id) : JWT 토큰 식별자
- 위의 크레임 또는 직접 추가해도 상관 없다.
{ 'iss': 'asdfasdf' .. 'my_custom': 'customm' }
Verify Signature
- Header와 Payload가 위변조되지 않았다는 사실을 증명하는 문자열이다.
- Base64 로 인코딩된 header 와 payload를 합친후 비밀키로 암호화를 진행한다.
- 암호화 알고리즘은 헤더에 적힌 알고리즘 방식을 사용해야한다. ```Verify_Signature alg = HS256 HMACSHA256( base64UrlEncode(header) + “.” + base64UrlEncode(payload), 256 비밀키 )
alg = PS512 RSAPSSSHA512(…) ```
최종적으로 발급된 토큰(Access Token)
- Header.Payload.Signature 형태가 된다.
- 제 3자가 토큰의
payload 정보
를 변경하여 보내어도 비밀키를 알지 못하여signature 부분
은 수정을 못한다. 따라서 서버는 payload에 변화가 있다는 것을 쉽게 탐지할 수 있다.
인증과정
발급받은 토큰을 이용한 요청 과정
-
Access Token 을 검증 할 때 서버의 공개키를 이용한다.
Verify Signature
부분을 공개키로 복호화 하고 header와 payload 부분을 비교한다. 이상이 없으면 검증을 성공적으로 통과한 것이다. - 장점
- 간편하다. 세션 저장소 처럼 별도의 저장소가 필요없다.
- JWT 발급 후 검증만 하면된다.
- 확장성이 띄어나다. 서버가 늘어나면 세션 저장소를 외부로 분리하는 작업을 해줘야한다. 하지만 토큰은 서버에 저장을 안하여 이러한 문제로 부터 자유롭다.
- 서버의 부담이 세션 방식보다 유리하다. 따로 저장소를 둘 필요가 없기 때문이다.
- 단점
- 세션키와 마찬가지로 사용자 토큰을 제 3자가 훔치고, 훔친 토큰을 이용하여 HTTP 요청을 보내면 서버는 사용자를 오인해 정보를 전달하게 된다.
- 토큰이 한번 제 3자에게 탈취되면 해당 토큰이 만료되기 전까지 속수무책으로 피해를 입을 수 밖에 없다.
- 세션 방식보다 훨씬 더 많은 네트워크 트래픽을 사용한다. 왜냐하면 head, payload, verify signature 을 사용하여 토큰을 만들기 때문이다.
Refresh Token 을 이용한 인증과정
Access Token
이 탈취 당할 것을 대비하여 유효기간을 짧게 하고Access Token
이 만료되었을 때 새로 발급요청하는 열쇠가 된다.- Refresh Token 은 긴 유효기간을 가진다.
- 예를 들면
Access Token
의 유효기간은 1시간, Refresh Token 의 유효기간은 1주라 하자. 그러면Access Token
이 만료되더라도, Refrech Token 을 이용하여Access Token
을 새롭게 발급받으면 된다. Access Token
과 같은 JWT 형태이다.
- 장점
- Access Token 을 가지고 있을 때 보다 안전하다.
- 단점
- 구현 방법이 복잡하다.
- Access Token 이 만료될 때마다 새롭게 발급하는 과정에거 HTTP 요청 횟수가 많아진다.
댓글남기기