구글로 로그인 시키는 방법은 잘 정리된 블로그들 많으니 참고

(필요 선행작업 : 구글 클라우드 플랫폼에서 클라이언트 ID 발급받기)

 

잘 쓰고 있던 구글 로그인 js 라이브러리가 deprecated 된다고 한다.

바꿔줘야한다.

 

바꿔주는 김에 OAuth 개념 정리

 

 

정리할 내용

  • Google Identity 간단 개념 (+ oauth)
  • 구글 라이브러리에서 변경되는 내용
  • authorization 에서 flow 선택
  • 라이브러리를 사용하지 않고 googl oauth api로 direct 요청하기
  • 토이플젝을 통해서 code → token 얻어내는 과정 및 유의사항
  • 기존 로그인 플로우 & 변경되는 로그인 플로우 설명

 

Google Identity

  • OAuth 2.0 개념
    • 인증을 위한 개방형 표준 프로토콜(약속)
    • 여러 서비스들(카카오, 구글, 네이버 등) 에서 통일된 Identity 체계를 사용하기 위해 모색된 개념
  • 사전에 꼭 정리해야하는 용어
    • Authentication
      • 유저의 신원 인증
      • id_token : 유저의 정보가 담긴 토큰
    • Authorization
      • 유저가 요청한 권한 부여
      • access_token : 이 토큰으로 필요한 서비스에 데이터 요청을 할 수 있다
  • UseCase
    1. 구글 계정으로 회원가입 및 로그인
    2. 구글 계정으로 회원가입 및 로그인 + 구글 API 사용(ex) 구글 캘린더, 구글 포토, 구글 드라이브 접근 권한 등)

 

[UseCase.2 의 플로우]

 

 

최대한 간단한 플로우를 먼저 개념잡고, 디테일하게 들어가는게 좋다

 

  1. 유저는 구글계정으로 로그인하여  authentization(신원확인)을 받는다. 그 결과로 authorization_code를 받는다.
  2. 받았던 authorization_code를 가지고, authorization(권한부여)를 받는다. 그 결과로 access_token을 받는다
  3. access_token을 가지고, 필요한 서비스의 데이터를 요청

 

1. GET -> 파라미터로 받아온 id로 해당되는 Cat 객체 찾기


router.get('/cats/:id', (req, res) => {
    try {
        const params = req.params;
        const cats = Cat.find((cat)=> { 
            return cat.id === params.id
        })
        res.status(200).send({
            success : true,
            data: {
                cats
            }
        })       
    }catch(error) {
        res.status(400).send({
            success: false,
            error : error.message
        })
    }
})

 

 

2. POST -> 신규 객체 추가

router.post('/cats', (req, res) => {
    try {
        const data = req.body
        console.log(data)
        Cat.push(data)
        res.status(200).send({
            success: true,
            data : {}
        })
    }
    catch(error){
        res.status(400).send({
            success: false,
            error: error.message
        })
    }
})

 

 

3. PUT -> 기존 객체 전체 갈아끼우기

router.put('/cats/:id', (req, res) => {
    try {
        const params = req.params;
        const data = req.body;
        let result
        Cat.forEach((cat) => {
            if(cat.id === params.id) {
                cat = data;
                result = cat;
            }
        })
        res.status(200).send({
            success : true,
            data: {
                cat : result
            }
        })       
    }catch(error) {
        res.status(400).send({
            success: false,
            error : error.message
        })
    }
})

 

 

4. PATCH -> 기존 객체 부분 수정

구조분해 할당 모르면 난리 브루스 펼쳐지는 부분

cat = { ...cat : 기존에 있던 객체들을 펼쳐서 오브젝트에 담기 => ...data : 새로 변경할 키-속성 값을 덮어 쓰기 }

 

router.patch('/cats/:id', (req, res) => {
    try {
        const params = req.params;
        const data = req.body;
        let result
        Cat.forEach((cat) => {
            if(cat.id === params.id) {
                cat = { ...cat, ...data}
                result = cat;
            }
        })
        res.status(200).send({
            success : true,
            data: {
                cat : result
            }
        })       
    }catch(error) {
        res.status(400).send({
            success: false,
            error : error.message
        })
    }
})

 

express 설치 후

 

post로 JSON 객체를 보내려는데, undefined 가 뜬다

 

post 라우터

app.post('/cats', (req: express.Request, res: express.Response) => {
    try {
        const data = req.body
        console.log(data)
        res.status(200).send({
            success: true,
            data : {}
        })
    }
    catch(error){
        res.status(400).send({
            success: false,
            error: error.message
        })
    }
})

 

포스트맨에서 테스트한 내용

 

백엔드 라우터에서 콘솔로그로 받은 req.body -> undefined

 

 

이는 아주 간단하게 해결된다

express가 json 데이터를 읽을 수 있도록 내장 미들웨어를 설정해 주기만 하면 된다

 

app.use(express.json())

 

express 라우터를 구성할 때 주의점은 순서가 중요하다는 것이다.

먼저 실행되어야 할 미들웨어들을 위로 올리고,

차례로 라우터들을 배치하고,

마지막에 not found 에러 처리를 위한 미들웨어 등 후순위 미들웨어를 배치한다

 

json 미들웨어를 추가하고 나서 정상적으로 req.body 가 찍히는 모습 확인

 

잘 디자인 된 웹 API 라면

1. 플랫폼 독립성 : 내부에서 어떤 방식으로 구현되는지와 관계없이 API를 호출할 수 있어야 한다. 표준 프로토콜을 사용

2. 서비스 진화 : API가 수정되어도(진화) 기존의 어플리케이션은 수정 없이 계속 작동할 수 있어야 한다.

 

기본 디자인 원칙

1. 리소스 중심 디자인, 클라이언트에서 접근할 수 있는 모든 종류의 개체, 데이터, 서비스가 리소스에 포함된다.

https://tacit.com/orders

2. 리소스마다 해당 리소스를 고유하게 식별하는 URI인 식별자가 있다.

https://tecit.com/orders/5

3. HTTP 요청은 독립적, 상태를 저장하지 않는다.

4. 표준 HTTP 동사 수행 : GET, POST, PUT, PATCH

5. 리소스 URI는 명사를 기반으로 해야한다

https://tecit.com/orders  // Good
https://tecit.com/add-order  // Bad

6. 여러 관계 수준을 탐색하기 위한 URI 제공시 -> 컬랙션/항목/컬렉션 보다 더 복잡하게 설계하지 않는 것이 좋다

https://tecit.com/customers/1/orders/99/products  // Bad

// Good : 2가지로 나누어서 제공
https://tecit.com/customers/1/orders
https://tecit.com/orders/99/products

7. API 요청이 많을 수록 웹서버의 부하를 높인다

8. Web API와 기본데이터 원본 사이에 종속성이 발생하지 않도록 해야한다. -> 관계형 데이터베이스 구조를 그대로 Web API 리소스로 사용할 필요가 없다.

예를 들어, premium_order, basic_order 이렇게 2가지 오더 테이블이 존재한다고 해서 /premium-orders, /basic-orders 와 같이 따라갈 필요가 없다. /orders처럼 관계형 데이터베이스를 추상화 한다.

9. 일부 작업을 특정 리소스에 매핑하지 못하는 경우 -> 의사 리소스로 표시하고 쿼리 문자열을 사용하여 필요한 매개 변수를 지정하는 URI를 제공한다

/add?operand1=99&operand2=1

 

HTTP 메서드 별 작업 정의

- GET : 리소스의 표현 검색, 응답메시지 : 리소스의 세부 정보

- POST : 새로운 리소스 생성, 요청메시지 : 새 리소스의 세부 정보

- PUT : 리소스를 만들거나 대체, 요청메시지 : 만들거나 업데이트할 리소스 지정

- PATCH : 리소스의 부분 업데이트, 요청메시지 : 리소스에 변경할 내용

- DELETE : 리소스 제거

 

 

HTTP 메서드 별 응답코드

메서드 응답코드 상태
GET 200 정상
  404 리소스를 찾을 수 없음
  204 요청이 처리 되었지만 응답 본문이 없음(콘텐츠 없음)
POST 201 새 리소스를 만드는 경우(만들어짐)
  200 일부 처리를 수행하지만 새 리소스를 만들지 않는 경우
  204 요청이 처리 되었지만 응답 본문이 없음(콘텐츠 없음)
  400 클라이언트가 잘못된 데이터를 요청에 배치한 경우 (잘못된 요청)
PUT 201 새 리소스를 만드는 경우(만들어짐)
  200 / 204 기존 리소스를 업데이트 할 경우(정상/내용없음)
  409 기존 리소스를 업데이트 할 수 없는 경우
PATCH    
     
     

 

비동기작업

POST, PATCH, PUT, DELETE와 같은 작업은 시간이 오래 걸리는 경우가 있다.

처리 작업이 완료될 때 까지 기다렸다가 클라이언트에게 응답을 보내는 경우, 클라이언트가 기다리다 지쳐 타임아웃을 낼 수가 있다.

이를 방지하기 위해, 요청이 수락되었지만 아직 완료되지 않았음을 나타내는 202(수락됨) 코드가 있다.

202 코드와 함께 location 헤더에 폴링할 엔드포인트 URI를 포함하여 응답한다.

HTTP/1.1 202 Accepted
Location: /api/status/12345

 

페이지네이션

쿼리 문자열로 개수를 서버쪽에서 필터링하여 응답한다.

https://tacit.com/orders?limit=25&offset=50

 

HMAC : Hash-based Message Authentication Code

해쉬 기반 메시지 신원확인 코드

 

클라이언트 👉 API 서버에 보내는 "요청자의 신원과 메시지의 무결성을 검증하기 위한 해쉬 문자열"

 

HMAC 만드는 방법

  • HMAC는 인증을 위한 Secret Key와 임의의 길이를 가진 Message를 해시함수를 이용해서 생성
  • 해시함수로 MD5, SHA-256등 일반적인 함수 사용가능
  • 각 알고리즘에 따라 다른 고정 길이의 MAC(=해시문자열 = 코드)이 생성된다

 

만약 중간에 해커가 코드를 가로채서 동일한 요청을 계속 보낸다면 (Reply attack), 이를 방지하기 위해서 MAC을 생성할 때 timestamp를 추가해서 사용하는 방법이 있다

API 서버는 해당 메시지가 생성된 시간을 알 수 있고, 생성된 시간부터 일정 시간 이내의 호출만 정상적인 호출로 인식 가능

serial, nonce 등 다른 값들도 룰에 따라 추가 가능

 

HMAC 생성과 API 통신에서 사용방법

1. (Client) 해시 생성

  • 클라이언트는 SHA-256(SecretKey, Message) = MAC 생성

2. 데이터 전송

  • 생성된 MAC + Message 를 API 서버에 전송, MAC은 HTTP Header 또는 쿼리로 (URL)에  포함된다

3. (Server) 해시 생성

  • API 서버는 클라이언트로부터 전달받은 Message 와 가지고 있던 SecretKey를 이용해 SHA-256(SecretKey, Message) = MAC 생성

4. 해시 비교 

  • API 서버에서 생성된 MAC과 클라이언트로부터 전달받은 MAC의 값이 같은지 비교 👉 무결성판단

 

구현 복잡도

Client_id & Client_secret < HMAC < PKI

 

 

예시

  • AWS S3 REST API 기준 HMAC 서명 생성과검증
  • 서명을 생성하는데 필요한 것은 API 서버가 정의한 룰 + 요청 자체에 담긴 여러 데이터(Message) + SecretKey 이다
  • 다양한 룰이 있는데, DomainTools의 경우 Client_id + timestamp + request_uri 조합한 문자열 + client_secret을 이용한 HMAC 생성
  • 서버도 동일한 방법으로 HMAC을 생성하여 클라이언트로 부터 받은 코드가 유효한지 검사

 

 

  • AWS S3 REST API 기준 인증방법
  • S3 REST API는 서버와 클라이언트 만이 공유하는 SecretKey를 사용하여 생성된 서명(HMAC)으로 매번 클라이언트로부터의 요청이 올바른지 매번 인증한다
  • 서버 - 클라이언트 사이의 요청 - 응답 메시지에 대한 보안은 HTTPS 프로토콜을 사용하는 것으로 자연스럽게 수행된다
  • 서명(Signature)은 단지 클라이언트가 진짜인지, 가짜인지 증명하는 역할만 수행
  • HMAC 생성을 위한 해쉬함수로는 SHA256이 사용된다
  • 생성된 Signature가 포함된 요청의 유효시간은 15분이다. 15분이 경과하면 유효하지 않은 요청으로 간주한다. timestamp의 포맷은 ISO8601에 타임존을 추가하여 정의한다

 

 

 

  • [코드예시-JAVA]
String sharedSecret = "5pKRnC5MGNuqEdKkzYy4MA";
String algorithm = "HmacSHA256";
String message = "2017-11-07T18:00:00+09:00 GET http://jsonobject.com/posts/2017";

// HMAC 생성기 초기화, 공유키, 알고리즘, 원본 메시지 지정
Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(sharedSecret.getBytes(), algorithm));

// Signature 바이트 배열 생성
byte[] signatureBytes = mac.doFinal(message.getBytes()));

// 생성된 Signature를 Base64 문자열로 변환, UMuelgDclhzNZPiNqF6NYkZtJnOFqlgu4i4t+4M1fJs=
String signature = Base64.getEncoder().encodeToString(signatureBytes);

 

  • [코드예시 - Binance API]

Request Body에 담아서 전송할 경우

 

앞에 여러가지 key-value 쌍들은 특정 API 메소드에 필요한 params 값들 + SecretKey -> SHA512로 암호화 -> 나온 결과값이 HMAC => 서명

    $ echo -n "symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1499827319559" | openssl dgst -sha256 -hmac "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j"
    (stdin)= c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71

API 요청 메시지 (필요한 params = message + HMAC 서명)

    (HMAC SHA256)
    $ curl -H "X-MBX-APIKEY: vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A" -X POST 'https://api.binance.com/api/v3/order' -d 'symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1499827319559&signature=c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71'

 

 

'programming > Web' 카테고리의 다른 글

[Express] Post로 JSON 데이터 보내기 (미들웨어 설정)  (0) 2022.08.20
Restfull 웹 API 디자인(1)  (0) 2022.08.20
AWS - EC2(EBS/AZ/ELB)  (0) 2022.04.06
[AWS] IAM 이란? (개념과 실습)  (0) 2022.04.05
API, SDK, Library, Framework  (0) 2022.03.10

Elastic Compute Cloud

ECC -> EC2

 

유동적인(탄력적인) 컴퓨터 클라우드

 

EC2 사용시 지불방법

1. on-demand : 시간단위로 가격이 고정되어 있음. 개발 초기단계, 유연한 크기 설정 가능

개발 시작 시간, 개발 끝나는 시간을 알수 없는 경우, 단기간에 개발을 할 수 있는경우, 개발 초기단계에서 EC2인스턴스에 테스트를 해볼때 적합함

 

2. reserved : 한정된 EC2 용량 사용가능, 지정석, 크기를 늘이고 줄이는 기능 없음, on-demand 보다 가격이 저렴함.

개발의 시작과 끝을 미리 알 수 있는 경우에 적합. 예상가능한 워크로드시 지정해두고 할인받아 사용가능

 

3. spot : 입찰 가격 적용, 가장 큰 할인률을 적용받을 수 있음. 

 

 

EC2는 어떻게 작동되는가? 무엇으로 구성되어있는가?

EBS : EC2 안에 부착되어있는 가상 디스크 

 

다양한 볼륨이 존재하므로 적절한 선택이 필요함

EBS 란? Elastic Block Storage

저장공간이 생성되어지며 EC2 인스턴스에 부착된다

디스크 볼륨 위에 File System이 생성된다

EBS는 특정 Availability Zone에 생성된다

 

Availability Zone(AZ)는 뭘까?

일명 가용 영역 = 데이터 센터 = IDC

하나의 Region(aws 제공 인프라 위치, 서울, 도쿄, 미국 등) 안에 여러개의 AZ가 존재할 수 있다.

일종의 DR(Disaster Recovery) 

 

다시 EBS로 돌아와서 볼륨 타입

<SSD군>

1) General Purpose SSD(GP2) : 최대 10K IOPS 지원, 1GB당 3IOPS 속도가 나옴

2) Provisioned IOPS SSD(IO1) : 극도의 I/O률을 요구(매우 큰 DB관리) 환경에서 주로 사용. 10K이상의 IOPS를 지원

 

<Magnetic/HDD군>

1) Throughput Optimized HDD(ST1) : 빅데이터, 로그 프로세싱시 주로 사용, boot 볼륨으로 사용 불가(os없음)

2) CDD HDD(SC1) : 파일서버와 같이 빈번한 입출력 없이 오랫동안 데이터 보관용, boot 볼륨으로 사용 불가

3) Magnetic (Sandard) : 가장 저렴, boot 볼륨으로 사용 가능

 

 

ELB(Elastic Load Balancers)

수많은 서버의 흐름을 균형있게 흘려보내주는 역할

병목현상 방지

 EC2 인스턴스가 unhealty 인스턴스가 되는경우 healty 인스턴스로 보내주는 역할

 

ELB종류

특정상황 - 어떤 ELB를 적절하게 사용해야 하는지

1) Application Load Balancer : OSI 7에서 작동됨,

HTTP, HTTPS같은 트래픽의 로드밸런싱 역할

라우팅설정을 따로 할 수 있어서, 특정 서버로 트래픽을 보내줄수 있다 (커스터마이징 가능)

 

2) Network Load Balancer : OSI 4에서 작동됨

극도의 퍼포먼스가 요구되는 TCP 트래픽에 적합함

구글이나 네이버같은 큰 서버에서 적합함

 

3) Classic Load Balancer : 현재 legacy로 간주됨, 따라서 거의 쓰이지 않음.

Layer7의 HTTP. HTTPS 라우팅 기능 지원

Layer4의 TCP 트래픽 라우팅 기능 지원

 

에러 처리

Load Balancer Error : 504 Error

주로 웹서버/데이터베이스 레이어에서 에러처리

 

X-Forwarded-For 헤더

public IP 주소로 접속(152.12.3.225)

DNS 를 통해

ELB에 도달 (private IP 10.0.0.23)

EC2(10.0.0.23) 으로 요청 보냄

 

-> EC2는 private IP 만 알수 있다. 즉 DNS에서 변환된 Private IP만 알수있으므로, 실제 요청의 원천은 알 수 없다

-> 이를 위해 X-Forwarded-For 헤더를 사용

 

Route53

AWS에서 제공하는 DNS 서비스

EC2 인스턴스/S3 Bucket / Load Balancer 서비스들에게 이름을 부여해주는 서비스

도메인 주소를 구매하여 연결

 

1. 도메인 등록(유료) 또는 타 사이트에서 도메인 생성

IAM 이란?

클라우드 사용자(유저)를 관리(권한 등)

 

1. 유저별로 다른 권한 부여기능(A: 데이터베이스 읽기 권한만 부여/ B: 데이터베이스 테이블 생성 권한만 부여)

2. 모든 유저들에게 비밀번호를 강제로 변경하도록 기한 설정 가능

3. MFA 다중인증 기능 : 루트유저는 필수

 

루트 유저로 생성할 수 있는 것

1) 그룹 : 유저 묶음

2) 유저

3) 역할

4) 정책 : json 형태로 되어있는 document를 가리킨다. 세밀한 접근권한을 일일히 설정하여 하나의 정책 document 생성

 

IAM 은 universal 하다 

universal (전역적) <-> regional (지역적)

 

IAM 정책 시뮬레이터(IAM과 관련 문제 디버깅하기 위한 툴)

1. 개발환경(Staging or Develop)에서 실제환경(Production)으로 빌드하기 전 IAM 정책이 잘 작동되는지 테스트하기 위함

2. IAM과 관련된 문제들을 디버깅하기에 최적화된 툴(이미 실제로 유저에 부여된 다양한 정책들도 테스트 가능)

 

 

[실습]

aws 콘솔에 로그인 - IAM 서비스

사용자 추가

1. 사용자(유저) 클릭 

2. 사용자 추가

3. 사용자 이름 설정

4. AWS 액세스 유형 선택

- 프로그래밍 방식 액세스 : 처음 유저를 생성할 때 액세스키/시크릿키 부여하고 그 키를 통해 접근

- 암호 : 콘솔에 로그인할 수 있도록 비밀번호 부여

두가지 다 선택, 또는 한가지만 선택 가능

 

5. 나머지 모두 디폴트 선택으로 진행

6. 사용자 추가 완료

 

그룹 추가

1. 그룹이름 지정

2. 디폴트로 진행

3. 그룹 추가 완료

 

사용자 그룹 지정

1. 그룹 클릭

2. 사용자 추가

3. 그룹에 사용자 추가 완료

 

정책

정책생성방법

1. GUI방법

2. json 도큐먼트 직접 작성

json 예시

 

유저에게 정책 추가 전 IAM 정책 시뮬레이터

: 유저별로 어떤 기능이 허용인지, 거절인지 바로 돌려볼 수 있다.

aws_user1은 아무런 정책을 갖고 있지 않기 때문에 모두 denied 거절 당한다.

 

유저에 정책 추가

 

유저에게 정책 추가 후 정책 시뮬레이터

 

'programming > Web' 카테고리의 다른 글

HMAC : API 통신 클라이언트 무결성 검증 방법  (0) 2022.06.28
AWS - EC2(EBS/AZ/ELB)  (0) 2022.04.06
API, SDK, Library, Framework  (0) 2022.03.10
CSS3 특성 선택자(Selector)  (0) 2022.03.05
REST Service에 대하여  (0) 2022.03.05

API

API : Application Program Interface

all about communication : 다른서비스끼리의 의사소통 방법

응용프로그램에서 운영체제나 프로그래밍언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스

연결, 다리

/naver-map/jamsil

구현과 독립적으로 사양만 정의되어있다

API에 따라 접근권한이 필요할 수 있다

open API : 노출된 API

구성 : 요청, 

 

Library

응용 프로그램 개발을 위해 필요한 기능(함수)를 모아놓은 소프트웨어

독립성을 가진다

응용프로그램이 능동적으로 라이브러리를 사용한다

library와 API의 차이점은 구현 로직의 유무이다

 

SDK 

SDK : Software Development Kit

소스코드의 모음과 유틸리티

Tool Box

실제로 API를 호출하는 코드

java, node, go, python -> 각각의 SDK 있다

java SDK, 안드로이드 SDK,

라이브러리와 프레임워크의 중간쯤?

목적에 맞게 라이브러리들을 모아놓은거

라이브러리 -> SDK -> 프레임워크

컴퓨터가 제공하는 기본적인 명령어 -> 반복 적인 작업이 있다면, 순서대로 나열하여 이름을 붙이면 프로그램이 된다 -> 명령어의 세트

 

Framework

틀 안에서 작업

응용프로그램이나 소프트웨어의 솔루션 개발을 수월하게 하기위해 제공된 소프트웨어 환경

상호협력하는 클래스와 인터페이스의 집합이다

응용프로그램이 수동적으로 프레임워크에 의해 사용된다.

 

 

'programming > Web' 카테고리의 다른 글

AWS - EC2(EBS/AZ/ELB)  (0) 2022.04.06
[AWS] IAM 이란? (개념과 실습)  (0) 2022.04.05
CSS3 특성 선택자(Selector)  (0) 2022.03.05
REST Service에 대하여  (0) 2022.03.05
HTTP 헤더 총정리  (0) 2022.03.04

특성 선택자란? 

주어진 특성의 존재 여부나 그 값에 따라 요소를 선택하는 것

<!-- html -->

<ul>
    <li><a title="hello" href="#">title link</a></li>
    <li><a className="hellologo" href="#internal">Internal link</a></li>
    <li><a href="https://example.com">https://example.com</a></li>
    <li><a href="#InSensitive">Insensitive internal link</a></li>
    <li><a href="http://example.org">http://example.org</a></li>
</ul>
/* css */

/* <a> elements with a title attribute */
a[title] {
  color: red;
}

/* <a> elements with an href matching "https://example.org" */
a[href="https://example.com"] {
  color: green;
}

/* <a> elements with an href containing "example" */
a[href*="example"] {
  font-size: 2em;
}

/* <a> elements with an href ending ".org" */
a[href$=".org"] {
  font-style: italic;
}

/* <a> elements whose class attribute contains the word "logo" */
a[class~="logo"] {
  padding: 2px;
}

 

[실행결과]

'programming > Web' 카테고리의 다른 글

[AWS] IAM 이란? (개념과 실습)  (0) 2022.04.05
API, SDK, Library, Framework  (0) 2022.03.10
REST Service에 대하여  (0) 2022.03.05
HTTP 헤더 총정리  (0) 2022.03.04
브라우저 저장소 비교 (localStorage, SessionStorage, Cookie)  (0) 2022.02.17

REST API란?

Representational State Transfer

웹을 좀 더 효율적으로 사용하기 위한 아키텍처

 

REST 구성

- 자원(URI)

- 행위(METHOD)

- 표현

 

REST 특징 ( 아직 모호한 개념 )

1) uniform interface : URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍처 스타일

2) stateless (상태없음) : 작업을 위한 상태가 따로 없음. API는 들어오는 요청만 단순히 처리.

3) Cacheable(캐시가능): HTTP가 가진 캐싱 기능이 적용됨, HTTP프로토콜에서 사용하는 헤더(Last-modifed, E-tag)를 이용하여 캐싱 구현 가능

4) Self-descriptiveness(자체 표현 구조) : REST API 만 보고도 쉽게 이해할 수 있는 자체적으로 표현능력도 있음.

5) Client-Server 구조 : 서버는 API제공, 클라이언트는 사용자 인증, 컨텍스트(세션, 로그인정보) 등을 직접 관리하는 구조, 각각 역할이 확실히 구분된다.

6) 계층형 구조 : 다중 계층으로 구성될 수 있으며, 로드밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있음. 프록시나 게이트웨이 같은 네트워크 기반의 중간매체를 사용 가능

 

REST 설계 가이드

1) URI는 정보의 자원을 표현해야한다

2) 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 표현한다.

3) 마지막 문자 슬래시는 작성하지 않는다.

4) 너무 긴 리소스의 경우 하이픈(-)을 사용하여 의미상 구분하여 가독성을 올린다(언더바(_)는 사용 안함)

5) 소문자가 적합

6) 파일의 확장자는 URI에 포함시키지 않는다.

7) 컬렉션과 도큐먼트의 개념에 따라 단/복수를 지킨다.

8) 리소스명은 동사보다 명사를 사용

  • GET /members/delete/1/ ---(X)
  • DELETE /member/1 ---(O)
  • http:// restapi.example.com/sports/soccer/players/13 ---sports : 컬렉션, soccor : 도큐먼트, players : 컬렉션, 13 : 도큐먼트
  • GET : /users/{userid}/likes/devices (관계명이 애매하거나 구체적 표현이 필요할 때)

9) 물리적 URLs를 사용하지 마라.

10) 데이터가 너무 많으면 paging을 해라

11) 응답은 정제해서 보내라. 응답을 수정하지 마라

12) GET 요청은 서버/DB의 상태 변화를 일으키지 않는다.

13) POST/PUT/DELETE 요청만 서버/DB의 상태를 변화시킨다. 

14) 클라이언트가 추가적인 액션을 위해 URLs을 구성하도록 두지말고, 실제 URLs를 응답에 담아라. 

예를 들어, 제품 리스트를 요청했을 때, 디테일 정보를 위한 링크를 제공한다고 할때

제품별 ID값들을 리턴하여, 다음과 같은 URL을 제공하지 말고, http://www.acme.com/product/PRODUCT_ID ---(X)

응답에 각각의 item 별로 실제 actual URL 을 제공해야한다. http://www.acme.com/product/001263 --- (O)

 

 

참고 http://rest.elkstein.org/2008/02/rest-design-guidelines.html

 

9. REST Design Guidelines

Some soft guidelines for designing a REST architecture: Do not use "physical" URLs. A physical URL points at something physical -- e.g., an ...

rest.elkstein.org

 

+ Recent posts