서버 인증
인증이 필요한 이유
- 인증은 프론트엔드의 관점에서 봤을 때 사용자의 로그인, 회원가입과 같은 사용자의 도입부분을 가리킨다. 반면 서버 관점에서 봤을 때는 모든 API요청에 대해 사용자를 확인하는 작업이다.
- 사용자A와 사용자B가 앱을 사용한다고 가정합니다. 두 사용자는 기본적으로 정보가 다르고 보유하고 있는 컨텐츠도 다르다. 따라서 서버에서는 A,B가 요청을 보냈을 대 누구의 요청인지 정확히 알아야 한다. 만일 그렇지 못한다면, 자신의 정보가 타인에게 유출되는 최악의 상황이 발생할 것이다. 그렇기 때문에 Front-end 에서는 자신이 누구인지를 알만한 단서를 서버에 보내야 하며, 서버는 그 단서를 파악해 각 요청에 맞는 데이터를 뿌려주어야 한다.
HTTP 요청
- 현재 모바일이나 웹 서비스에서 가장 많이 쓰이는 통식 방식이다. HTTP 통신은 응답 후 연결을 끊기게 되며, 과거에 대한 정보를 전혀 담지 않는다. 이 말은 현재 보낼 HTTP 요청을 지난 번 내 정보를 담아 보냈던 HTTP 요청과 전혀 관계가 없다는 말이다. 따라서 각각의 HTTP 요청에는 주체가 누구인지에 대한 정보가 필수적이다.
- 서버에 요청을 보내는 작업은 HTTP 메세지를 보내는 것이다. HTTP 메세지의 구조는 아래와 같다.
- HTTP 메시지 타입에는 두 가지가 있다. Request는 클라이언트가 서버로 전달하는 메시지, Response는 Request에 대한 서버의 답변이다. HTTP메시지는 ASCII로 인코딩된 텍스트 벙보이며, 이러한 메시지는 설정파일(프록시 서버), API(브라우저 경우) 혹은 다른 기타의 인터페이스에 의해 가공되어 제공 된다.
HTTP Request 메시지 구조
1) Start Line
Start Line에는 HTTP 메소드, Request target, HTTP version이 있습니다.
- HTTP 메소드는 요청의 의도를 담고 있는 GET, POST, PUT, DELETE 등이 있다. GET은 존재하는 자원에 대한 요청, POST는 새로운 자원을 생성, PUT은 존재하는 자원에 대한 변경, DELETE는 존재하는 자원에 대한 삭제와 같은 기능을 가지고 있다.
- Request target은 HTTP Request가 전송되는 목표 주소이다.
- HTTP version은 version에 따라 Request 메시지 구조나 데이터가 다를 수 있어서 version을 명시한다.
2) Header
Header에는 HTTP Request 그 자체에 대한 정보를 담고 있다. key : value 형태로 이루어져 있다.
이 Header에 경우 Request, Response에만 있는 Header 외에 공통 Header도 있기에 여기선 Request Header에만 정보는 아래와 같다.
Host : 요청하려는 서버 호스트 이름과 포트번호
User-agent : 클라이언트 프로그램 정보. 이 정보를 통해 서버는 클라이언트 프로그램(브라우저)에 맞는 최적의 데이터를 보내줄 수 있다.
Referer : 바로 직전에 머물렀던 웹 링크 주소
Accept : 클라이언트가 처리 가능한 미디어 타입 종류 나열
If-Modified-Since : 여기에 쓰여진 시간 이후로 변경된 리소스 취득. 페이지가 수정되었으면 최신 페이지로 교체한다.
Authorization : 인증 토큰을 서버로 보낼 때 쓰이는 Header
Origin : 서버로 Post 요청을 보낼 때 요청이 어느 주소에 시작되었는지 나타내는 값. 이 값으로 요청을 보낸 주소와 받는 주소가 다르면 CORS(Cross-Origin Resource Sharing) 에러가 발생한다.
Cookie : 쿠키 값이 key-value로 표현된다.
3) Body
HTTP Request가 전송하는 데이터를 담고 있는 부분이다. 전송하는 데이터가 없다면 Body 부분은 비어있다.
보통 POST 요청일 경우, HTML 폼 데이터가 포함되어 있다.
HTTP Response 메시지 구조
1) Start Line
Response의 Start Line에는 HTTP version, Status Code, Status Text가 있다.
- Staus Code는 Response 상태를 나타내는 코드입니다. 요청 정상 처리를 나타내는 200이나 페이지가 이동되거나 없어졌을 때를 나타내는 404와 같은 코드로 이 부분은 추후에 정리 하겠습니다.
- Status Text는 Response 상태를 간략하게 글로 설명해 줍니다.
2) Header
Location : 301, 302 상태코드일 때만 볼 수 있는 Header로 서버의 응답이 다른 곳에 있다고 알려주면서 해당 위치(URI)를 지정합니다.
Server : 웹 서버의 종류
Age : max-age 시간내에서 얼마나 흘렀는지 초 단위로 알려주는 값
Referrer-policy : 서버 referrer 정책을 알려주는 값 ex) origin, no-referrer, unsafe-url
WWW-Authenticate : 사용자 인증이 필요한 자원을 요구할 시 , 서버가 제공하는 인증 방식
Proxy-Authenticate : 요청한 서버가 프록시 서버인 경우 유저 인증을 위한 값
3) Body
HTTP Request 메시지의 Body와 동일하다. 마찬가지로 전송하는 데이터가 없으면 비어있다.
공통 Header
Date : 현재시간
Cache-Control : 캐시 제어
+ no-store : 캐시를 저장하지 않겠다
+ no-cache : 모든 캐시를 쓰기 전에 서버에 해당 캐시를 사용해도 되는지 확인하겠다
+ must-revalidate : 만료된 캐시만 서버에 확인하겠다.
+ public : 공유 캐시에 저장해도 된다.
+ private : '브라우저' 같은 특정 사용자 환경에만 저장하겠다.
+ max-age : 캐시의 유효시간을 명시하겠다.
Transfer-Encoding : Body 내용 자체 압축 방식을 지정
Content-Encoding : Body의 리소스 압축 방식 (Transfer-Encoding은 Body 자체이므로 다름)
Content-type : Body의 미디어 타입 ex) application/json, text/html
Content-Length : Body의 길이
Content-language : Body를 이해하는데 가장 적절한 언어 ex) ko
Connection : 클라이언트와 서버의 연결 방식 설정. HTTP/1.1은 keep-alive로 연결 유지하는게 디폴트 입니다.
서버 기반 인증 시스템(Session/Cookie)
- 세션 기반의 인증 시스템이다. 서버 측에서 사용자들의 정보를 기억하기 위해 세션을 유지하는데, 이는 메모리, 디스크, 데이터베이스 등을 통해 관리한다.
- 클라이언트로부터 요청을 받으면 클라이언트의 상태 정보를 저장하여 유지해야 하므로 Stateful한 구조를 가진다.
[ 인증 방식 ]
- 사용자가 로그인 시 올바른 사용자임을 확인하고, 고유한 세션 ID값을 부여해 세션 저장소에 저장하고 클라이언트에게 발급해준다.
- 클라이언트는 세션 ID를 받아 쿠키에 저장하고, 인증이 필요한 요청마다 쿠키에 세션ID를 담아 헤더에 보낸다.
- 서버에서는 쿠키를 받아 세션 저장소와 비교해 올바른 요청인지 확인한다.
- 인증이 완료되고 서버는 요청에 응답한다.
[ 장점 ]
- 중요한 정보는 서버에 있기 때문에 쿠키 자체(세션 ID)에는 유의미한 값을 가지고 있지 않다.
[ 단점 ]
- 해커가 훔친 쿠키를 이용해 HTTP 요청을 보내면 서버에서는 올바른 사용자가 보낸 요청인지 알 수 없다.(세션 하이재킹) => 세션에 유효한 시간을 넣어줘야 한다.
- 서버에 세션을 저장하므로 사용자가 증가함에 따라 과부하를 줄 수 있어 확장성이 용이하지 못한다.
- 시스템 확장이 어렵다.
토큰 기반 인증 시스템
- 위와 같은 단점을 극복하기 위해 "토큰 기반 인증 시스템"이 나왔다. 인증받은 사용자에게 토큰을 발급해주고, 서버에 요청을 할 때 HTTP 헤더에 토큰을 함께 보내 인증받은 사용자인지 확인한다. (유효성 검사)
- 서버 기반 인증 시스템과 달리 사용자의 인증 정보를 서버에 저장하지 않고 클라이언트의 요청으로만 인가를 처리하므로, Stateless한 구조를 가진다.
- 세션/쿠키 방식과 유사하게 클라이언트는 Access Token(JWT)를 HTTP 헤더에 실어 서버로 보낸다.
[인증 방식]
- 사용자가 로그인 시 올바른 사용자임을 확인하고, 클라이언트에게 Access Token(JWT)을 발급해준다.
- 클라이언트는 전달받은 토큰을 저장해 두고, 인증이 필요한 요청마다 토큰을 HTTP 헤더에 담아 보낸다.
- 서버에서는 암호화된 토큰을 복호화 해 올바른 요청인지 확인한다.
- 인증이 완료되고 서버는 요청에 응답한다.
[장점]
- 서버 기반 인증 시스템은 저장소의 관리가 필요하지만, 토큰 기반은 Access Token을 발급해준 후 요청이 들어오면 검증만 해주면 되기 때문에 추가 저장소가 필요 없다. 즉 Stateless 하다.
- 쿠키를 사용함으로 인해 발생하는 취약점이 사라진다. 하지만, 토큰을 사용하는 환경에서의 취약점에 대비해야 한다.
- 확장성이 뛰어나다. 토큰 기반으로 하는 다른 인증 시스템에 접근이 가능하다. Ex) facebook, Google 등
[단점]
- 이미 발급된 JWT를 돌이킬 수 없다. 서버 기반 인증 시스템처럼 저장소를 사용하는 경우에는 해당 세션이 악의적으로 사용될 경우 지워버리면 되지만, JWT는 한 번 발급되면 유효기간이 완료될 때 까지는 계속 사용이 가능하다.
- 즉, 유효기간이 지나기 전까지 실컷 털릴 수 있다.
- JWT의 길이가 길다. 인증이 필요한 요청이 많아질수록 서버의 자원 낭비가 발생한다.
JWT (JSON WEB TOKEN) ?
- JWT 란 JSON 포맷을 이용해 사용자에 대한 속성을 저장하는 Claim 기반의 웹 토큰이다.
- JWT는 토큰 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달한다.
- JWT는 주로 static 변수와 로컬 스토리지에 저장한다고 한다. static 변수에 저장하는 이유는 HTTP 통신을 할 때마다 JWT를 HTTP 헤더에 담아서 보내야 하는데, 이를 로컬 스토리지에서 계속 불러오면 오버헤드가 발생하기 때문이다.
JWT(JSON WEB TOKEN)의 구조

- JWT는 세 파트로 나누어지며, 각 파트를 점( . )으로 구분한다.
- 각 순서대로 헤더(header), 페이로드(payload), 서명(signature)로 구성되고, JSON 형태인 각 부분은 BASE64로 인코딩 되어 표현된다.
1. Header(헤더)
: 토큰의 타입과 해시 암호화 알고리즘으로 구성된다.
alg는 헤더를 암호화 하는 것이 아닌, Signature를 해싱하기 위한 알고리즘을 지정하는 것이다.
|
{ |
|
"alg": "HS256", |
|
"typ": "JWT" |
|
} |
typ : 토큰의 타입을 지정한다.
alg : 알고리즘 방식을 지정하며, 서명(Signature) 및 토큰 검증에 사용한다.
2.Payload(내용)
: 토큰에 사용자가 담고자 하는 정보를 담는 곳
Payload에는 토큰에서 사용할 정보의 조각들인 Claim 이 담겨있고,
이는 JSON(Key/Value) 형태의 한 쌍으로 이루어져 있다. 클레임의 종류는 아래와 같이 크게 3 종류로 나누어져 있다.
2-1 등록된 클레임(Registered Claim)
등록된 클레임은 토큰 정보를 표현하기 위해 이름이 이미 정해진 종류의 데이터이다.
등록된 클레임의 사용은 모두 선택적이지만, 사용할 것을 권장한다.
iss : 토큰 발급자 (issuer)
sub : 토큰 제목 (subject)
aud : 토큰 대상자 (audience)
exp : 토큰의 만료시간 (expiraton) : NumericDate 형식으로 되어 있어야 한다.
nbf : 토큰 활성 날짜(not before) : 이 날이 지나기 전의 토큰은 활성화되지 않는다.
iat : 토큰 발급 시간(issued at) : 토큰 발급 이후의 경과 시간을 알 수 있다.
jti : JWT 고유 식별자(JWT ID) : 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용한다.
|
{ |
|
"iss": "dev-coco.tistory.com", |
|
"exp": "1602076408", |
|
"https://dev-coco.tistory.com/jwt": true, |
|
"userId": "dev-coco" |
|
"username": "coco" |
|
} |
위의 예시에는 2개의 Registered Claim과 1개의 Public Claim 그리고 2개의 Private Claim으로 이루어져 있다.
2-2 공개 클레임(Public Claim)
공개 클레임은 사용자 정의 클레임으로, 충돌이 방지된 이름을 가져야 하며, 충돌 방지를 위해 클레임 이름을 URI 형식으로 짓는다.
|
{ |
|
"https://dev-coco.tistory.com/jwt": true |
|
} |
2-3 비공개 클레임(Private Claim)
비공개 클레임은 사용자 정의 클레임으로, 클라이언트와 서버가 협의하에 임의로 지정한 정보를 저장해서 사용한다.
|
{ |
|
"userId": "dev-coco" |
|
"username": "coco" |
|
} |
3. Signature(서명)
: 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다.
헤더(Header)와 내용(Payload)의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀키를 이용해
헤더에서 정의한 알고리즘으로 해싱을 하고, 이 값을 다시 BASE64로 인코딩하여 생성한다.
|
HMACSHA256( |
|
base64UrlEncode(header) + "." + |
|
base64UrlEncode(payload), |
|
secret |
|
) |
위의 Header + Payload + Signature를 합치면 아래의 비밀스런 코드가 완성된다.

그리고 위 코드를 Decoded하면 아래 처럼 뜨게 된다.

API
API란?
- API는 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있는 인터페이스를 뜻한다. - 위키 백과
- 인터페이스란 컴퓨터 시스템끼리 정보를 교환하는 공유 경계를 의미한다. 말 그 대로 어떤 기계간의 장치끼리 정보를 교환하기 위한 수단이나, 방법을 의미한다.
- API는 UI(User Interface)와 비슷한 상호작용 역할을 하며, 이는 서로 다른 시스템이 만나 동작하기 위한 의사소통 역할을 하며, 데이터 전달 및 처리하며, 사용자에게 여러 응용 프로그램의 작업을 수행하고 완료하는데 있어서 언제 어디서나 정보를 제공하고 있다. 반면에 UI와는 달라 사용자의 눈에는 보이지 않는다.
- 요악하면, 작성된 프로그램은 API에게 데이터를 요청하게 되고, API는 요청받은 명령을 처리하기 위해 응용 프로그램 및 어플리케이션과 상호작용을 하게 된다. 이 후 결과물을 작성된 프로그램에게 전달하게 된다. 이러한 방식으로 API는 프로그램들이 서로 상호작용을 할 수 있도록 요청, 명령, 처리하는 인터페이스.
API의 접근 방식
- Private API : API를 기업이나 연구 단체 등에서 사용하는 다양한 어플리케이션과 시스템의 통합을 위해 사용하는 것으로 단체 내부에서만 사용할 수 있도록 하는 것.
- Partner API : API를 특정 비지니스 파트너와 공유하는 것으로, 공유받은 API를 품질 저하 없이 사용할 수 있으며 수익 창출을 목표로 사용하는 것.
- Public API : 모든 사람들에게 API를 제공하는 것으로, 개인이 API와 상호작용하는 프로그램을 무료로 개발할 수 있다. 다양한 아이디어를 통해 혁신적인 프로그램의 등장을 목표로 사용되고 있음.
API의 장점
- 자동화가 용이 : API를 통해 사람이 직접 조작하지 않아도 관련 내용이 자동으로 생성되고 처리되어 워크플로우가 빨라질 수 있다.
- 범위의 확장성 : API는 프로그램 사용 시 정보를 전달하는 기능이 있어 사용자의 환경에 맞춰서 전달할 수 있다. 또한 API에 직접 액세스하지 않아도 콘텐츠가 자동적으로 생성 및 업로드 되어 확장에 용이함.
- 적용력 : API는 변화 예측에도 큰 도움이 되기 때문에 API를 통해 데이터를 수집하고 전달하는데 있어서 유연한 서비스 환경을 구축할 수 있음.
오픈 API의 종류
- 여러 국내 및 해외 등 다양한 기업에서 오픈 API를 제공하고 있다. 이를 통해 창업을 목표로 하는 개발자 또는 실습을 목표로 하는 개인 개발자들에게 무료로 제공되고 있어 독창적이고 새로운 프로그램들이 등장하는 것을 목표로 대중들에게 무료로 지원하고 있다. 대표적으로 구글, 네이버, 카카오 등이 있다.
구글 : cloud.google.com/apis?hl=ko
네이버 : developers.naver.com/main/
카카오 : developers.kakao.com/
1주차 느낀점
1주차에는 미니프로젝트로 팀원들과 간단한 웹사이트를 만들었다.
나는 클라이언트와 서버간의 reqeust, response 메시지 정보를 어떻게 하면 자유자재로 사용할 수 있는지, jwt를 이용하여 사용자에 대한 정보를 어떻게 활용할지에 대해 공부하고 훈련하는 것에 집중했다. 나중에 어떤 분야에서든 개발을 하는데에 있어서 이런 지식들이 중요하다고 생각이 되기 때문에, 꾸준히 공부를 하고 부족한 부분을 채워나가야 할 것 같다.
사실 개인적으로 가장 어려웠던 점은 git을 통한 협업이었는데, github에 개인적으로 공부한 것만 올려봤지, 원격 레포지토리에서 clone을하고, branch를 나누고, pull을 하고, merge를하고 ,,,, 이런건 처음이었어서 오류가 날때마다 어떻게 해결해야 할지 막막했다. 그래도 조금씩 정보를 찾아보면서 어찌저찌 되기는 했지만, 앞으로 git으로 협업을 할 때 제대로 할 수 있을까 걱정이 된다.
처음 접하는 팀 프로젝트이기도 하고, 서버 구축에 대한 개념이나 방법을 모르는 상태로 진행을 해야해서, 사실 처음에는 막막했지만 정보를 공유하는 팀원들과, 구글이라는 아주 좋은 형님(?)이 있기 때문에 모양 정도는 갖출 수 있었던 것 같다.
겪어보지 못한 특별한 경험이었고,
마지막으로, 끝까지 포기하지 않고 함께해준 팀원들과 잘 이끌어준 조장님에게 감사합니다.
참고 :
// 느낀점을 제외한 작성된 위 모든 내용은 아래 사이트를 참고하였습니다.
API란 무엇인가? (about API)
1. API의 등장 프로그램을 개발하기 위해서는 많은 인력과 데이터를 요구하며 체계적이고 간결함을 요구하고 있습니다. 그렇기 때문에 기업에서 다양한 분야의 프로그램을 개발하기 위해서는 많
ittrue.tistory.com
https://mangkyu.tistory.com/56?category=925341
[Server] JWT(Json Web Token)란?
현대 웹서비스에서는 토큰을 사용하여 사용자들의 인증 작업을 처리하는 것이 가장 좋은 방법이다. 이번에는 토큰 기반의 인증 시스템에서 주로 사용하는 JWT(Json Web Token)에 대해 알아보도록 하
mangkyu.tistory.com
https://strange-developer.tistory.com/50
[golang] JWT 활용하기
JWT란? JWT는 JSON Web Token의 약자로, 특정 환경에 있는 사용자의 권한 요청이나 데이터를 안전하게 전달하는 표준이다. JWT에는 두 가지 주요 장점이 있는데, 하나는 여러 프레임워크에서 사용할 수
strange-developer.tistory.com
https://ohcodingdiary.tistory.com/5
HTTP Request / Response 메시지 구조
오늘은 HTTP Request(요청)와 Response(응답) 메시지 구조에 대해 알아보겠습니다. HTTP 메시지는 서버와 클라이언트 간에 데이터가 교환되는 방식입니다. 이때 메시지 타입은 두 가지가 있습니다. Reques
ohcodingdiary.tistory.com
https://tansfil.tistory.com/58?category=255594
쉽게 알아보는 서버 인증 1편(세션/쿠키 , JWT)
앱 개발을 처음 배우게 됐을 때, 각종 화면을 디자인해보면서 프론트엔드 개발에 큰 흥미가 생겼습니다. 한때 프론트엔드 개발자를 꿈꾸기도 했었죠(현실은 ...) 그러나 서버와 통신을 처음 배
tansfil.tistory.com