비밀번호 전송 양방향 암호화(rsa) 적용

  • view에서 서버로 계속 같은 비밀번호 전송하는걸 막기위해 rsa 양방향 암호화 적용

1.Rsa util 추가

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class Rsa {

    public static String RSA_WEB_KEY = "_RSA_WEB_Key_"; // 개인키 session key
    public static String RSA_INSTANCE = "RSA"; // rsa transformation

    /**
     * 복호화
     *
     * @param privateKey
     * @param securedValue
     * @return
     * @throws Exception
     */
    public String decryptRsa(PrivateKey privateKey, String securedValue) throws Exception {
        Cipher cipher = Cipher.getInstance(Rsa.RSA_INSTANCE);
        byte[] encryptedBytes = hexToByteArray(securedValue);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        String decryptedValue = new String(decryptedBytes, "utf-8"); // 문자 인코딩 주의.
        return decryptedValue;
    }

    /**
     * 16진 문자열을 byte 배열로 변환한다.
     *
     * @param hex
     * @return
     */
    public static byte[] hexToByteArray(String hex) {
        if (hex == null || hex.length() % 2 != 0) { return new byte[] {}; }

        byte[] bytes = new byte[hex.length() / 2];
        for (int i = 0; i < hex.length(); i += 2) {
            byte value = (byte) Integer.parseInt(hex.substring(i, i + 2), 16);
            bytes[(int) Math.floor(i / 2)] = value;
        }
        return bytes;
    }

    /**
     * rsa 공개키, 개인키 생성
     *
     * @param request
     */
    public void initRsa(HttpServletRequest request) {
        HttpSession session = request.getSession();

        KeyPairGenerator generator;
        try {
            generator = KeyPairGenerator.getInstance(Rsa.RSA_INSTANCE);
            generator.initialize(1024);

            KeyPair keyPair = generator.genKeyPair();
            KeyFactory keyFactory = KeyFactory.getInstance(Rsa.RSA_INSTANCE);
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();

            session.setAttribute(Rsa.RSA_WEB_KEY, privateKey); // session에 RSA 개인키를 세션에 저장

            RSAPublicKeySpec publicSpec = (RSAPublicKeySpec) keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);
            String publicKeyModulus = publicSpec.getModulus().toString(16);
            String publicKeyExponent = publicSpec.getPublicExponent().toString(16);

            request.setAttribute("RSAModulus", publicKeyModulus); // rsa modulus 를 request 에 추가
            request.setAttribute("RSAExponent", publicKeyExponent); // rsa exponent 를 request 에 추가
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

2. jsp에 필요 js 추가 및 hidden 값추가

<script type="text/javascript" src="${_.contextPath}/resources/lib/RSA/rsa.js"></script>
<script type="text/javascript" src="${_.contextPath}/resources/lib/RSA/jsbn.js"></script>
<script type="text/javascript" src="${_.contextPath}/resources/lib/RSA/prng4.js"></script>
<script type="text/javascript" src="${_.contextPath}/resources/lib/RSA/rng.js"></script>
<form> ...
                                <input type="hidden" id="RSAModulus" value="${RSAModulus}"/>
                                <input type="hidden" id="RSAExponent" value="${RSAExponent}"/>
</form>

3. js에 암호화 로직 추가 및 암호화

// 비밀번호 암호화
function rsa(pwd){
    var pw = pwd;
    // rsa 암호화
    var rsa = new RSAKey();
    rsa.setPublic($('#RSAModulus').val(),$('#RSAExponent').val());
    return rsa.encrypt(pw);
}
function bindLoginSubmit() {
  $("#form_login").submit(function (e) {
    e.preventDefault();
    var form = this;
    var options = {
      method: form.method
      /*, data: $(form).serialize()*/
      , data: {
          "username" :  rsa($("input[name='username']").val())
          ,"password" : rsa($("input[name='password']").val())
      }
    };
})
};

4. WebSecurityConfig에 RequestContextListener 추가 (HttpRequest 불러오기위해)

    @Bean
    public RequestContextListener requestContextListener(){
        return new RequestContextListener();
    }

5. 복호화 및 암호화 AuthenticationProvider에 추가

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        try {
            ServletRequestAttributes servletRequestAttribute = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = servletRequestAttribute.getRequest();
            Rsa r = new Rsa();
            HttpSession session = request.getSession();
            //로그인전에 세션에 저장된 개인키를 가져온다.
            PrivateKey privateKey = (PrivateKey) session.getAttribute(Rsa.RSA_WEB_KEY);
            //암호화 된 비밀번호를 복호화 시킨다.
            String username = r.decryptRsa(privateKey, (String) authentication.getPrincipal());
            String password = r.decryptRsa(privateKey, (String) authentication.getCredentials());
            // ShA 256 암호화 = 단방향
            password = passwordEncoder.encode(password).replaceAll("\\{sha256}","");
        }
}

vue

  • 단일 페이지 어플리케이션

vue 설치

  1. 노드,NPM 설치
    • mac brew 사용시 명령어 brew install node
  2. vue cli 설치
    • 명령어 npm install -g @vue/cli
    • vue cli 는 vue project를 빠르게 구성하고, 빌드, 디플로이 할 수 있게 하는 도구.
  3. vue 프로젝트 생성 (vue-project)
    • 명령어 vue create vue-project
    • 여러설정이가능한 vue-project-manually 도 있다. 명령어 vue-project-manually
  4. 생성된 프로젝트로 접속해 vue 구동 테스트
    • 명령어 npm run serve -- --port 3000

vue 프로젝트 구조

node_modules : npm으로 설치된 패키지 파일들(자바로 치면 lib)
public : 웹팩을 통해 관리되지 않는 정적 리소스가 모여있는 디렉토리
src/asset : 이미지, css, 폰트 등을 관리하는 데렉토리
src/components : vue 컴포넌트 파일이 모여 있는 디렉토리
App.vue : 최상위(Root) zjavhsjsxm
main.js : 가장 먼저 실행되는 자바스크리브 파일로써, Vue 인스턴스를 생성하는 역할
babel.config.js : 바벨 설정 파일
package-lock.json : 설치된 package의 dependency 정보를 관리하는 파일
package.json : 프로젝트에 필요한 package를 정의하고 관리하는 파일

 

쿠키

 

HTTP는 무상태 프로토콜이기에 쿠키 미사용시엔 클라이언트가 서버에 접속했는지 계속 확인할 수 없다.

사용하는 예

1)로그인후에 유저 정보를 서버가 알기 위해 사용한다.

 

Set-Cookie

- 서버에서 클라이언트로 쿠키 전달(Response)

 

Cookie

- 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청 시 서버로 전달

 

즉, 서버가 쿠키를 전달하면 클라이언트는 저장하고 항상 보내준다.

모든 요청에 자동으로 포함한다.

 

보안을 위해 쿠키를 서버를 세팅할때 세션 아이디를 생성해서 사용한다.

세션 아이디를 통해 서버에서 누군지 해석한다.

 

사용처

- 사용자 로그인 세션 관리에서 사용한다.

- 광고 정보 트래킹

 

쿠키 정보는 항상 서버에 전동 됨

- 최소한의 정보만 사용

- 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지(localStorage, sessionStorage) 참고

 

주의점

- 보안에 민감한 데이터는 저장하면 안 됨(주민번호, 신용카드 번호)


쿠키 생명주기

Expires(날짜), max-age(시간)

쿠키를 계속 유지할 수 없기에 날짜, 시간을 제한한다.

 

세션 쿠키

- 만료 날짜를 생략하면 브라우저 종료 시까지만 유지

 

영속 쿠키

- 만료 날짜를 입력하면 해당 날짜까지 유지


쿠키-도메인

명시

- 명시한 문서 기준 도메인+ 서브 도메인 포함

- domain=example.org로 설정할 경우

- example.orgdev.example.org 모두에 접근 가능하다.

 

생략 : 현재 문서 기준 도메인만 적용


쿠키 - 경로

이 경로를 포함한 하위 경로 페이지만 쿠키 접근

일반적으로 path=/ 루트로 지정


쿠키 - 보안

Secure, HttpOnly, SameSite

 

Secure

- Https에서만 전송한다.

 

HttpOnly

- XSS 공격 방비

- 자바스크립트에서 접근 불가(document.cookie)

- http 전송에만 사용

 

SameSite

- XSRF 공격 방지

- 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 전송

 

 

 

 

전송방식

단순 전송

- 콘텐츠의 길이를 할 때 사용한다.

- Content-Length 

 

압축 전송

- 컨텐츠의 용량이 클 때 압축해서 전송한다.

- Content-Encoding

 

분할 전송

- 컨텐츠를 분할해서 전송한다.

- 종료시에 0 \r\n으로 표현한다.

- 분한 전송시엔 Content-Length이 포함되지 않는다.

- Transfer-Encoding

 

범위 전송

- 클라이언트가 요청한 범위를 전송한다.

- Request = Ranges: Bytes=1001~2000

- Response = Content-Range: bytes 1001~2000 / 2000 <-끝길이


일반정보

단순한 정보성 헤더이다.

 

From

- 유저 에이전트의 이메일 정보

Referer 

- 이전 웹 페이지의 주소 (구글에서 검색해서 다른 페이지로 접속 시 구글이 표현된다)

- 유입경로를 분석할때 사용한다.

User-Agent

- 유저 에이전트 애플리케이션 정보(즉 클라이언트 애플리케이션 정보)

- 특정 브라우저에서의 오류를 체크할 수 있다.

- Request에서 사용한다.

Server

- 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보

- 중간에 거치는 프록시 서버가 아닌 진짜 처리하는 서버 정보를 제공한다.

- Response에서 사용한다.

Date

- 메시지가 발생한 날짜와 시간

- Response에서 사용한다.

 


특별한 정보

 

Host

- 요청한 호스트 정보(도메인)

- 필수

- 하나의 서버가 여러 도메인을 처리해야 할 때 사용한다.

- IP로만 통신하기에 필요하다.

- Host: aaa.com

 

Location

- 웹 브라우저가 3xx 응답 결과에 Location헤더가 있으면, Location 위치로 자동 이동

- 201 : Location 값은 요청에 의해 생성된 리소스 URI

 

Allow

- 허용 가능한 HTTP 메서드

- 405 (Method Now Allowed) 에서 응답에 포함해야 함

- Allow: GET, HEAD, PUT

 

Retry-After

- 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간

- 날짜 단위, 초 단위로 표현 가능하다.

 


인증

 

Authorization

- 클라이언트 인증 정보를 서버에 전달한다.

- Basic xxxxxxxxx

 

WWW-Authenticate

- 리소스 접근 시 필요한 인증 방법 정의

- 401 Unauthorized 응답과 함께 사용

- WWW-Authenticate : Newauth realm=“apps”…

표현

리소스(데이터)를 어떤 표현으로 전달할지를 의미한다.

즉, 서버와 클라이언트가 주고받는 전송 형태를 말한다.

json으로, xml으로 표현한다.

Content-Type  표현 데이터의 형식
Content-Encoding 표현 데이터의 압축 방식
Content-Language  표현 데이터의 자연언어
Content-Length 표현 데이터의 길이

 

표현 헤더는 reqeust, response 둘 다 사용

 

Ex)

HTTP/1.1 200 OK

Content-Type : application/json

Content-Length : 16



{“data”:”hello”}

 

Content-Encoding

     - gzip등으로 압축했을 때 클라리언트에서 압축방식을 알아야 하기에 표현을 전달할 때 사용한다.

 

Content-Length

     - ko,en등 한국어, 영어 표현

 

Content-Language

     - byte단위로 표현의 길이를 나타낸다.

 


협상(콘텐츠 네고시에이션)

클라이언트가 선호하는 표현 요청

 

Accept 클라이언트가 선호하는 미디어 타입 전달
Accept-CharSet 클라이언트가 선호하는 문자 인코딩
Accept-Encoding 클라이언트가 선호하는 압축 인코딩
Accept-Language 클라이언트가 선호하는 자연 언어 

협상헤더는 reqeust에서만 사용한다.

 

예를 다중언어를 지원하는 서버에서 기본이 영어일 때 한국어를 요청할 때 사용한다.

 

 

협상과 우선순위1

Quality values

우선순위를 설정해서 서버에 요청한다

Accept-Language : ko-KR, ko;ko;q=0.9, en-US;9=0.8

1.ko-KR;q=1(q=1은 생략)

2.ko;q=0.9

3.en-US;q=0.8

 

식으로 숫자가 큰 순으로 우선순위를 정해 요청한다.

 

협상과 우선순위 2

Quality values(q)

구체적인 것이 우선한다.

Accept : text/*, text/plain, text/plain;format=flowed, */*

 

협상과 우선순위 3

구체적인 것을 기준으로 미디어 타입을 맞춘다.

 

스프링 빈이란?

스프링이 객체를 생성해 들고 있는다.

즉, 스프링 컨테이너가 생성될 때 컨트롤러(빈)가 같이 생성된다.

 

why?

객체를 계속 생성할 필요가 없고 미리 생성해 그것을 사용한다.

 

빈과 의존관계

 

컨트롤러(@Controller) -> 서비스

컨트롤러로 요청이 들어오면 서비스를 통해 비즈니스 작업을 해야 하기에 컨트롤러가 서비스에 의존한다.

 

의존관계 주입방법

컨트롤러, 서비스를 다 빈으로 등록해준다.

의존관계를 생성할 땐 @Autowired를 사용한다.

 

빈등 록 방식

1. 컴포넌트 스캔

2. 자바 코드로 스프링 빈 등록

 

빈 등록은 메인 메서드가 있는 패키지부터 시작한다.

즉, 하위 패키지에 있는 것만 등록된다.


자바 코드로 빈 등록하기

 

@Configuration

public class SpringConfig {



    @Bean

    public MemberService memberService() {

        return new MemberService(memberRepository());

    }



    @Bean

    public MemberRepository memberRepository(){

        return new MemoryMemberRepository();

    }

}

애노테이션으로 등록하기

@Aspect
@Component
public class TimeTraceAop {

    @Around("execution(* hello.hellospring..*(..))")
    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
        long start =  System.currentTimeMillis();
        try {
            return joinPoint.proceed();
        } finally {
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println(joinPoint.toString()+" / timeMs : "+timeMs+"ms");
        }

    }
}

@Component,@Service,@Repository 대신 자바로 등록할 수 있다.

정형화된 코드(@Service,@Repository)는 컴포넌트 스캔을 사용한다.

 

또, 생성자로 빈을 생성하는 게 제일 안전하다.

    private final MemberRepository memberRepository;
	
    //생성자
    @Autowired
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

스프링 웹 개발 기초

 

1. 정적 컨텐츠

서버에서 파일을 웹브라우저에 그냥 내려준다.

resources 경로 안에 static, public안에 html은 스프링 부트에서 자동으로 올려준다.

/hello-spring/src/main/resources/static 경로 안 파일 확인

-rw-r--r--  1 mac  staff  222  8  9 14:10 hello-static.html

-rw-r--r--  1 mac  staff  227  8  9 10:52 index.html

 

정적컨텐츠 가져오는 순서

클라이언트 요청 -> 컨트롤러 체크(우선순위는 컨트롤러) -> 없을 경우 static, public 경로 파일 있는지 확인

 

2.MVC와 템플릿 엔진

Model View Controller

 

View : 화면을 그리는데 집중해야 한다.

Model, Controller : 비지니스 로직에 집중한다.

 

Code

@GetMapping("hello-mvc")

public String helloMvc(@RequestParam(value = "name") String name, Model model){

    model.addAttribute("name",name);

    return "hello-template";

}

 

 

3.API

View를 사용하지 않고 데이터를 바로 내릴 수 있다.

@ResponseBody를 사용할 경우 viewResolver 대신 httpMessageConverter가 동작한다.

기본 문자 처리

StringMessageConverter

기본 객체 처리

MappingJackson2 MessageConverter

요새는 보통 json형태로 데이터를 제공해준다.

Ex)

{

"name": "test"

}

 

Code

@GetMapping("hello-string")

@ResponseBody

public String helloString(@RequestParam(value = "name") String name, Model model){

    return "hello "+name;

}

'개발 소발 > 개발 Spring' 카테고리의 다른 글

Spring form login RSA 암호화 적용  (0) 2022.08.18
Spring Bean,스프링 빈이란?기초  (0) 2021.08.13
Spring DispatcherServlet 기초개념  (0) 2020.08.06
Spring Environment 기초 사용방법  (0) 2020.07.13
Spring Scope란?  (0) 2020.07.13

클라이언트에 서버로 데이터 전송

 

주로 GET에선 쿼리 파라미터로 전송한다.

body도 되긴 하나 잘 사용하지 않는다.

POST, PUT, PATCH에선 HTTP 메시지 body로 보낸다.

 

정적 데이터 조회

- GET을 사용한다.

- 쿼리 파라미터를 사용하지 않는다.

- 이미지를 가져올 때 사용한다.

 

동적 데이터 조회

- GET을 사용한다.

- 쿼리 파라미터를 기반으로 결과를 동적으로 생성

- 검색어 = 필터 라한다.

 

HTML FORM 전송

- POST를 사용한다.

- 웹 브라우저가 FORM데이터를 읽어 HTTP 메시지를 생성해준다.

- Content-Type : application/x-www-form-urlencoded

- HTTP 메시지 바디에 담아 서버로 보낸다.

- GET으로 변경도 가능하나 데이터 변경 작업이 있으면 사용하면 안 된다.(조회에서 사용 가능)

 

HTML FORM 데이터 전송

- multipart/form-data

- form에 파일을 담아 보낼 때 사용한다.

- 파일만 가는 게 아니라 form데이터 전체를 보낸다.

- Content-Type: multipart/form-data;boundary=123

- 바운더리로 구분한다.

 

HTTP API 전송

- 서버 TO 서버

- 앱 클라이언트

- 웹 클라이언트(ajax, React, Vue)

- GET, POST, PUT, PATCH 다 사용 가능하다.

- Content-Type : application/json을 주로 사용한다.

 


HTTP API 설계 예시

리소스 기반(/members)으로 설계한다.

 

[

회원 목록 /members -> GET

회원 등록 /members -> POST

회원 조회 /members/{id} -> GET

회원 수정 /members/{id} -> PATCH, PUT, POST

회원 삭제 /members/{id} -> DELETE

]

 

HTTP API - 컬렉션

(서버가 관리하는 리소스 디렉터리)

- POST 기반 등록

POST로 등록할 시 등록될 URI정보를 모른다.

서버에서 RESPONSE에 Location을 담아준다.

즉, 서버에 요청해 서버가 정해준다.

 

HTTP API - 스토어

(클라이언트가 관리하는 리소스 저장소)

- PUT 기반 등록

클라이언트가 직접 리소소의 URI를 지정한다.

클라이언트에서 서버에 원격으로 데이터를 넣을 때 사용한다.

클라이언트가 파일 이름을 알고 있고 파일을 업로드할 때 사용한다.

 

POST, PUT 중에선 주로 POST를 사용한다.

 

HTTP FORM 사용

GET, POST만 지원한다.

컨트롤 URI를 사용한다. ex) /members/{id}/delete

FORM은 GET,POST만 지원해 제약이 있다.

제약을 해결하기 위해 동사로 된 리소스 경로를 사용한다.

/members/{id}/delete


좋은 URI 설계 개념

 

문서

- 단일 개념(파일 하나, 객체 하나)

-/members/100

 

컬렉션

- 서버가 관리하는 리소스 디렉터리

- 서버가 리소스의 URI를 생성하고 관리

 

스토어

- 클라이언트가 관리하는 자원 저장소

- 클라이언트가 리소스의 URI를 알고 관리

 

컨트롤러, 컨트롤 URI

- 문서, 컬렉션, 스토러로 해결하기 어려운 추가 프로세스 실행

- GET, POST, PUT, PATCH만으로.

- /members/{id}/delete

http 메서드

 

http api 설계 방법

회원 정보 관리 API를 만들어라.

 

리소스 기반으로 설계해야 한다.

회원이라는 개념이 리소스이다.

/members <-회원 개념 리소스

 

회원 목록 조회 /members

회원 조회 /members/{id}

회원 등록 /members/{id}

회원 수정 /members/{id}

회원 삭제 /members/{id}

 

리소스와 행위를 분리한다.

행위란? 조회, 등록, 삭제, 변경

 

조회, 등록, 수정, 삭제가 다 /members/{id} 이렇게 사용할 때

여러 http메서드를 사용한다.

즉, 행위는 http 메서드로 구분한다.

 

http 메서드 종류

GET : 리소스 조회

POST : 요청 데이터 처리, 주로 등록에 사용

PUT : 리소스를 대체, 해당 리소스가 없으면 생성

PATCH : 리소스 부분 변경

DELETE : 리소스 삭제

HEAD : GET과 동일하지만 메시지 부분을 제외하고, 상태 줄과 헤더만 반환

OPTIONS : 대상 리소스에 대한 통신 가능 옵션(메서드)을 설명(주로 CORS에서 사용)

CONNECT : 대상 자원으로 식별되는 서버에 대한 터널을 설정

TRACE : 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행


자주 쓰는 메서드

GET

1. 리소스 조회

2. 서버에 전달하고 싶은 데이터는 query를 통해서 전달

3. 메시지 바디를 사용해서 데이터를 전달할 수 있지만, 지원하지 않는 곳이 많아서 권장하지 않는다.

 

POST

1. 요청 데이터 처리

2. 메시지 바디를 통해 서버로 요청 데이터 전달

3. 서버는 요청 데이터를 처리

- 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행한다.

4. 주로 전달된 데이터로 신규 시로스 등록, 프로세서 처리에 사용

 

**메시지 바디를 통해 들어온 데이터를 처리한다.

**신규 데이터 등록 등에 사용한다.

POST로 보내면 저장하기로 서버와 약속한다.

 

# 서버에 요청 Request

POST /members

{

“userName”:”choi”,

“age”:20

}

 

# 서버의 응답 Response

HTTP/1.1 201 Created

Content-Type:application/json

Content-Length:34

Location:/members/100

{

“userName”:”choi”,

“age”:20

}

 

요청 데이터를 처리한다는 것은 무슨 뜻 일까?

대상 리소스가 리소스의 고유 한 의미 체계에 따라 요청에 포함된 표현을 처리하도록 요청합니다.

예제 )

1.FORM데이터 처리

2. 게시판 글쓰기 댓글 달기

3. 서버가 아직 식별하지 않은 새 리소스 생성

4. 기존 자원에 데이터 추가

 

딱 정해진 것은 아니고 정하기 나름이다.

 

1. 새 리소스 생성

2. 요청 데이터 처리(서버에서 변화가 일어남)

3. 값 하나를 바꾸는 것이 아닌 프로세스 상태 변경에서 사용됨

4. 컨트롤 URI에 사용된다.

5. 다른 메서드로 처리하기 애매하면 POST를 사용한다.

 

PUT

1. 리소스를 완전 대체

- 리소스가 있으면 대체

- 리소스가 없으면 생성

- 쉽게 이야기해서 덮어버림

2. 클라이언트가 리소스 위치를 알고 URI 지정

- 클라이언트가 리소스 위치를 알고 URI 지정

- /members/100

3. 값을 대체하기에 하나의 값만 변경할 수 없다.

 

PATCH

1. 리소스 부분 변경

- 업데이트라고 생각하면 된다.

2. 서버에서 PATCH를 사용하지 못하면 POST를 사용한다.

 

DELETE

1. 리소스 제거

- 삭제


HTTP 메서드의 속성

1. 안전(Safe Methods)

2. 멱등(Idempotent Methods)

3. 캐시 가능(Cacheable Methods)

 

1. 안전

-호출해도 리소스를 변경하지 않는다.

-데이터가 변경 없는 메서드(GET, HEAD)

 

2. 멱등

-한 번 호출하든 두 번 호출하든 100번 호출하든 결과가 똑같다.

-GET,PUT,DELETE

-POST는 벽등이 아니다. 주문 시 계속 주문된다.

-똑같은 요청을 두 번 해도 괜찮다

 

3. 캐시 가능

- 응답 결과 리소스를 캐시 해서 사용해도 되는가?

- 스펙상 GET, HEAD, POST, PATCH 캐시 가능

- 실제로는 GET, HEAD 정도만 캐시로 사용

- POST, PATCH는는 바디 까지 캐시 키로고려해야하 하는데, 구현이 쉽지 않다.

'개발 소발 > 기초 컴퓨터,통신' 카테고리의 다른 글

HTTP 표현,협상 이란?  (0) 2021.08.13
HTTP 데이터 전송 기초  (0) 2021.08.06
비연결성,Http메시지 란?  (0) 2021.08.03
URI,URL,URN,http,Stateless이란?  (0) 2021.08.03
HTTP기초,PORT,DNS 란?  (0) 2021.08.03

 

비연결성(Connectionless)

 

TCP/IP는 연결을 유지한다.

요청 <-> 응답 형태

 

근데 서버에 연결된 클라이언트가 많아지면 서버의 부하가 많이 된다.

 

비연결성의 사용 이유!

연결을 유지하지 않는 모델은 서버가 유지해야 하는 자원이 줄어서 좋다.

 

HTTP는 기본적으로 연결을 유지하지 않는다.

Request, Response 형식으로 요청하고 응답이 오면 종료한다.

연결을 바로바로 끊게 되면 수천 명이 사용해도 동시에 들어오는 건 매우 적다.

 

비연결성의 단점

1.TCP/IP 연결에 필요한 3 way handshake 시간이 계속 추가된다.

2. 웹 브라이저로 사이트를 요청하면 HTML뿐만 아니라 자바스크립트, css, 추가 이미지 등 수많은 자원이 함께 다운로드된다.

 

처리방법

하나당 연결 후 끊는 게 아니라 다천리 될 때까지는 연결을 유지한다.

연결
자바스트립트
css
추가이미지
종료
형식으로 사용한다.

http 메시지

 

http는 모든 바이너리 데이터를 다 전송할 수 있다.(이미지, html, json 등등)

http를 사용하는 이유!

 

http 메시지 구성 형식

Start-line 시작라인
Header 헤더
Empty line 공백 라인(CRLF) <- 무조건 있어야한다.
Message body

공식 스펙도 이렇게 되어있다.

 

Request(요청)

요청 시 메시지 구성요소에 들어가는 것

시작 라인 request-line

1.Http 메서드

- GET, POST, PUT, DELETE 등이 있다.

 

2. 요청 대상

- 대부분 절대 경로 이후의 값이 들어간다.

- /search?q=hello&hl=ko

3.Http 버전

- HTTP/1.1

 

Request(응답)

응답 시 메시지 구성요소에 들어가는 것

시작 라인 status-line

1.Http 버전

 

2.HTTP상태 코드(요청 성공, 실패를 나타냄)

- 200 : 성공

- 400 : 클라이언트 요청 오류

- 500 : 서버 내부 오류

 

3. 이유 문구

- 사람이 읽을 수 있는 오류 문구


Http header  

Key:Value 형태로 구성된다.

Key는 대소문자 구분하지 않는다.

value는 당연히 대소문자를 구분한다.

 

Http header 용도

http 전송에 필요한 부가 정보가 모두 포함되어있다.

서버와 협의 시에 부가 정보도 추가할 수 있다. 

ex) 특정 헤더 값 추가

KEY-TEST : "바보"


HTTP 메시지 바디

실제로 전송할 데이터가 포함된다.

 

 

 

+ Recent posts