백엔드와 프론트엔드는 api를 통해 정보를 요청하고 이에 응답한다. 정보는 요청을 보낸 주체가 누군가에 따라 달라지고 이를 위해서는 요청을 보낸 주체, 즉 사용자가 누구인지에 대한 확인 작업이 필요하다. 이를 '인증'이라 한다

서버에 요청을 보내는 작업은 HTTP 통신을 통해 이루어진다. HTTP 통신은 쉽게 말해 HTTP 메세지를 보내는 것으로 메세지는 헤더와 바디로 이루어져있다. 헤더에는 기본적인 요청 정보가 들어있고, 바디에는 서버로 보내야 할 데이터가 들어간다.

그럼 인증 방식 종류를 알아보자.

 

1. 계정정보 ( id, pw)를 요청 헤더에 넣는 방식 

- 가장 단순하며 보안이 가장 낮은 방식. 단순하게 HTTP 메세지에 사용자의 계정정보를 그대로 넣어 서버에게 보낸다. 아무 처리가 필요없기에 빠르지만, 보안에 매우 취약하고 매 요청이 들어올 때마다 서버는 DB를 조회하여 들어온 계정정보를 비교해야 한다. 보안이 낮은 이유는 비암호화된 HTTP 요청을 가로채서 계정정보를 알 수 있기 때문이다.

 

2. 세션 / 쿠키 방식

- 사용자가 암호화된 방식으로 한번 로그인을 하면 서버에서 고유한 세션을 만들어 저장소에 저장

- 서버는 그 세션을 열 수 있는 'key'가 되는 세션 ID를 사용자에게 발행

- 클라이언트는 받은 세션 ID를 쿠키에 저장하여 요청 때마다 쿠키를 전달

- 서버는 쿠키가 유효한지 검증 후 그에 맞는 유저 정보를 얻어 가공된 데이터 응답

보안상 서버는 사용자의 개인 컴퓨터보다는 훨씬 안전하기 때문에 인증에 Session을 이용한다.

세션 ID는 브라우저 단위로 저장되고 브라우저 종료시 소멸된다.  사용자의 로그인 여부, 닉네임 등 사용자가 요청 할 때 마다 필요한 정보들을 세션에 담아두면 디비에 접근할 필요가 없어서 효율적이다.

만약 HTTP 요청에서 쿠키를 탈취하여 정보를 가로챌 수 있다. ( 세션 하이재킹 공격) -> HTTPS 프로토콜 사용 or 세션 유효시간(만료시간)을 설정

세션 저장소를 사용해야 하므로 부가저긴 저장공간 필요

 

3. 토큰 기반 인증 방식 JWT

기존 일반 토큰은 의미 없는 문자열 기반으로 구성되어 있다.

토큰을 보낼 때는 json형식으로 토큰을 담아 보내었다. 그런데 이런 일반 토큰 방식은 단순한 문자열이기에 정보를 담을 수 없었고, 토큰을 만료시킬 수단이 없었다. 더욱이 발급된 토큰 검사를 위해 매 요청마다 디비에 접근하여 자원을 쓰게 되다. 이를 어느 정도 해결한 방법이 Claim 기반 토큰 방식이다. 여기서 Claim은 사용자 정보나 데이터 속성 등을 의미하며 Claim 토큰이라 하면 이런 정보들을 담고 있는 토큰이다.

그 중 대표적인 토큰이 JWT 토큰이다. JSON WEB TOKEN의 줄임말로 JSON을 이용한 WEB 표준 토큰이다.

JWT는 Header, Payload, Signature로 나눠져 있으며 '.'으로 각 형태를 구분한다. 각 값은 BASE64로 인코딩 되어 있다.

Header

    - 헤더에는 typ, alg 두 가지 정보가 담겨있다. typ는 토큰의 타입을 뜻하며 JWT 토큰이므로 jwt를 담고 있다.

alg는 해싱 알고리즘을 뜻하며 주로 HMAC SHA256을 사용하고 이 alg는 Signature에서 사용한다.

결국 {"alg":"HS256", "typ":"JWT"} 라는 문자열을 BASE64로 인코딩하게 된다.

Payload

    - 페이로드에는 위에서 Claim이라 부르는 정보들이 저장되어 있다. Key/Value 형태로 저장된다.

Claim에는 세 분류로 나눌 수 있다. 1. 등록된 클레임 , 2. 공개된 클레임 , 3. 비공개 클레임

1. 등록된 클레임 : 서비스에서 필요한 정보가 아닌, 토큰에 대한 정보들을 담기위해 이름이 이미 정해진 클레임이다.

현재 SSHJ에서는 토큰의 만료시간을 나타내는 "exp"를 사용 중이다.

 

2. 공개 클레임 : 충돌이 방지된 이름을 가지고 있어야 한다. 이를 위해 이름을 URI 형식으로 짓는다.

 

3. 비공개 클레임 : 등록된 클레임도 아니고, 공개된 클레임도 아니다. 양 측간에 협의 하에 사용되는 클레임 이름들이다.

SSHJ에서는 userId, loginId, nickname 등 토큰을 보낸 클라이언트이 정보를 담기 위해 사용 중이다.

위 정보들 또한 문자열을 BASE64로 인코딩한다.

 

Signature

    - JWT의 마지막 부분은 서명이다. Header의 인코딩값, Payload의 인코딩값을 합친 후 Secret Key로 해싱한 값입니다.

HMACSHA256( BASE64UrlEncode(header)+"."+BASE64UrlEncode(payload), secretKey)로 나타낼 수 있다.

 

즉 JWT = header.payload.signature로 표현한다.

 

토큰 방식은 서버에서 따로 저장을 할 필요가 없어 공간 면에서 효율적이다. 하지만 토큰 방식에서도 어떤 토큰 방식을 쓰냐에 따라 저장 공간의 필요성 유무도 바뀌게 된다. 토큰 방식의 종류는 다음 포스트에서 알아보저

'Spring Boot' 카테고리의 다른 글

searching for @size: false log  (0) 2020.12.03
WEB SOKCET vs REST API 차이  (0) 2020.11.12
0. 스프링 부트는 스프링과 어떻게 다를까?  (0) 2020.11.08
2. 토큰 방식의 종류  (0) 2020.11.02
Redis - Can't start Redis Server  (0) 2020.09.20