좌충우돌 개발

REST API

|
기술 구성 : HTTP + JSON
구성

Resource : 명사형으로 표현한다
Message : http body 담아서 보낸다
Method : http method
POST : CREATE
GET : SELECT (Idempotent)
PUT : UPDATE (Idempotent)
DELETE : DELETE (Idempotent)

장점
  • 상태정보를 관리하지 않는다.
  • Uniform Interface : HTTP + JSON 구조이면 어떤 플랫폼을 사용 가능
  • Http의 캐시 기능 활용
  • Self-descriptiveness : API 메시지만 보고도 이해할 수 있는 구조
  • 클라이언트 서버 구조
  • 계층형 구조 : ex) 마이크로 서비스 아키텍처
단점
  • RDBMS에 맞추기가 어렵다 : 복합KEY 사용
  • 표준이 없다
REST API 디자인 가이드
  1. REST URI는 단순하고 직관적으로 만들자
  2. 리소스 간의 관계를 표현하는 방법
    • 서브 리소스로 표현하는 방법 : /users/terry/dogs
    • 서브 리소스에 관계를 표현하는 방법 : /users/terry/has/dogs
  3. 에러 처리
    • 200 - 성공
    • 400 Bad Request - field validation 실패 시
    • 401 Unauthorized - API 인증, 인가 실패
    • 404 Not found - 해당 리소스 없음
    • 500 Internal Server Error - 서버 에러
  4. 버전관리
     {servicename}/{version}/{REST URL}  
    

    외부에서는 api url로 통해 들어오고 reverse proxy를 사용하여 URL 매핑을 사용 한다. 외부 노출된 URL변경이 없이 향후 확장되었을 때 서버를 물리적으로 분리해내기 편리하다.

  5. 페이징
    Record?offset=100&limit=25
  6. 부분 응답 처리
    API를 요청하는 클라이언트의 용도에 따라 선택한 필드만을 보내서 전체 네트워크의 대역폭을 절약할 수 있다.
     /terry/friends?field=id,name  
    
  7. 검색(전역 검색과 지역 검색)
    검색은 HTTP GET에서 쿼리 스트링 검색 조건을 정의하는 경우가 일반적인데 , 이 경우 검색 조건이 다른 쿼리 스트링과 섞여 버릴 수 있다.
    URLEncode를 써서 표현하고, 구분자를 사용하게 되면 검색 조건은 다른 쿼리 스트링과 분리된다. 이 검색 조건은 서버에 의해서 토큰 단위로 파싱 되어야 한다
    전체 검색: /search?q=id={}
    Resource 검색: /resource?q=id={}
  8. HATEOS를 이용한 링크 처리
    Hypermedia as the engine of application state의 약어로, 하이퍼미디어의 특징을 이용하여 HTTP 응답에 다음 액션이나 관계된 리소스에 대한 HTTP 링크를 함께 반환하는 것이다.
  9. 단일 API 엔드포인트 활용
    Reverse Proxy
REST API 보안
  1. REST API 보안 관점
    • 인증(Authentication) : 누가 서비스를 사용하는지를 확인하는 절차
    • 인가(Authorization) : 해당 리소스에 대해서 사용자가 사용권한이 있는지 확인 하는 과정
    • 네트워크 레벨 암호화 : 일반적으로 HTTPS를 사용한다
    • 무결성 보장 : 변조 방지
    • 메시지 본문 암호화 : 전체 암호화 보다는 특정 필드만 암호화를 주로 사용한다.
  2. 인증
    • API 키 방식 : 모든 클라이언트가 같은 키를 공유함으로 권장하지 않는다
    • API 토큰 방식 : 아이디와 비밀번호로 사용자를 인증한 후 API를 호출에 사용할 기간이 유효한 API토큰을 발급하여 API 토큰으로 사용자를 인증하는 방식 HTTP
    • Basic Auth : 사용자 아이디와 비밀번호를 Base64로 인코딩하여 http 헤더에 저장하여 서버에 전송하여 인증하는 방식이다. 중간에 패킷을 가로채면 사용자 정보가 노출됨으로 반드시 https로 통신 하여야 한다. Digest Access Authentication : 클라이언트가 인증을 요청할 때 클라이언트가 서버로부터 nonce이라는 일종의 난수 값을 받고(서버와 클라이언트는 이 난수값을 서로 알고 있음), 사용자 ID와 비밀번호를 이 난수 값을 이용해서 해시화 하여 서버로 전송하는 방식이다.
    • 클라이언트 인증 추가
    • 제3자 인증 방식 (Oauth 2.0 Authorization grant type) : ex)페이스북 인증
    • IP 화이트 리스트를 이용한 터널링
    • Bi-directional Certification (Mutual SSL) : 클라이언트에도 인증서를 두고 SSL 통신하는 방식
    • JWT 방식(JSON Web Token)
      • Claim 기반 토큰의 개념 : Oauth의 access_token은 특별한 정보를 담지 않은 랜덤 문자열
      • Claim : 사용자에 대한 property나 속성
      • Oauth 1.0과 JWT의 차이점 : Oauth1.0에서 발급한 토큰과 권한 정보를 매핑한 정보를 서버 측에 저장하고 있다 요청이 들어오면 토큰과 저장되 토큰을 비교 하여 resource룰 반환 한다. JWT에서는 토큰에 사용자 아이디와 권한 정보를 담아 base64로 인코딩하여 클라이언트로 보내고 서버에는 토큰 정보를 가지고 있지 않는다. 요청이 들어오면 토큰내의 정보를 가지고 resource를 반환여부를 판단한다.
    • JWT 소개
      • Claim (메시지) 정의 : Claim에는 줄 바꿈이 있기 때문에 base64로 인코딩하여 하나의 문자열로 만든다.
      • 변조 방지 : 변조 방지를 위하여 HMAC을 사용한다.
      • 서명 생성 방식
      • 전체 메시지 포맷
    • JWT 문제점
      • 길이 : claim이 길어질수록 토큰 길이도 길어진다. 호출 시 마다 사용됨으로 대역폭 낭비가 발생한다.
      • 한번 발급된 토큰은 값을 수정하거나 폐기가 불가 : 만료시간을 명시적으로 둔다. Refresh Token등을 이용해서 중간마다 토큰을 재발행 한다.
      • 암호화 : 기본적으로 Claim에 대한 정보를 암호화 하지 않는다. 토큰자체를 암호화 하는 방법은 JWE(JSON Web encryption)이다
  3. 권한 인가
    API 인가 방식
    - RBAC(Role Based Access Control) : Role로 권한을 묶고 role을 부여하는 방식
    - ACL(Access Control List) : 직접 권한 부여 방식

    API 권한 인가 처리 위치
    - 클라이언트에 의한 API 권한 인가 처리
    - 게이트웨이에 의한 권한 인가 처리
    - 서버에 의한 API 권한 인가 처리 : 가장 일반적이고 보편적인 인가 방식

    네트워크(전송) 레벨 암호화
    - Man in the middle attack : 해커는 인증기관의 인증서를 사용 할 수 없으므로 반드시 서버의 인증서를 확인 하도록 한다. 메시지 본문 암호화
    - RSA 알고리즘
    메시지 무결성 보장
    - HMAC에 timestamp를 사용 하여 무결성 및 재사용 공격을 방어한다.

  4. 자바스크립트 클라이언트 지원
    SPA(Single Page Application) : 브라우저간 이동 없이 자바스크립트를 이용해서 동적으로 페이지를 변경할 수 있는 방식

    SPA의 경우 서버와 통신을 자바스크립트가 직접 XMLHttpRequest 객체를 이용해서 API를 호출 하는 형태

    동일 출처 정책에 대한 처리
    siteA.com에서 로딩한 스크립트에서 api.my.com으로 API를 XMLHttpRequest를 호출하게 되면 동일 출처 정책에 의해서 호출 에러 발생

    프록시를 이용한 방식
    Reverse Proxy를 넣어서 전체 URL을 같게 만든다.

    특정 사이트에 대한 접근 허용 방식
    HTTP 요청의 응답을 주면서 HTTP 헤더에 Request Origin(요청을 처리해 줄수 있는 출처)를 명시 해준다.

      Access-Control-Allow-Origin: sitea.com => sitea.com만 허용
     Access-Control-Allow-Origin: * => 모든 사이트 허용
    

    Pre-flight를 이용한 세세한 CORS 통제
    웹 브라우저에서는 XMLHttpRequest를 특정 URL에 요청하기 전에 먼저 HTTP OPTIONS를 호출한다. 그러면 서버는 해당 URL에 접근할 수 있는 Origin URL과 HTTP 메서드를 반환해 준다. 이를 Pre-flight 호출이라고 하는데, 이 정보를 기반으로 브라우저는 해당 URL에 XMLHttpRequest를 보낼 수 있다.

    자바스크립 클라이언트를 위한 API Access Token에 대한 인증 처리

    API Access Token을 보안 쿠키를 통해서 주고 받는다.
    API Access Token은 해당 세션에서만 유효하도록 한다.

Comments