[SK shieldus Rookies 19기] 애플리케이션 보안 1일차

기록하는짱구·2024년 3월 12일
0

SK Shieldus Rookies 19기

목록 보기
9/43
post-thumbnail

인프라 활용을 위한 파이썬

질문 상세 페이지(템플릿)에 부트스트랩 적용

  • templates\pybo\question_detail.html
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'bootstrap.min.css' %}">

<div class="container my-3">
	<h2 class="border-bottom py-2">{{ question.subject }}</h2>

	<div class="card my-3">
		<div class="card-body">
			<div class="card-text" style="white-space: pre-line;">
				{{ question.content }}
			</div>
			<div class="d-flex justify-content-end">
				<div class="badge badge-light p-2">
					{{ question.create_date }}
				</div>
			</div>
		</div>
	</div>

	<h5 class="border-bottom my-3 py-2">
		{{ question.answer_set.count }}개의 답변이 있습니다.
	</h5>
	{% for answer in question.answer_set.all %}
	<div class="card my-3">
		<div class="card-body">
			<div class="card-text" style="white-space: pre-line;">
				{{ answer.content }}
			</div>
			<div class="d-flex justify-content-end">
				<div class="badge badge-light p-2">
					{{ answer.create_date }}
				</div>
			</div>
		</div>
	</div>
	{% endfor %}

	<form action="{% url 'pybo:answer_create' question.id %}" method="post" class="my-3">
		{% csrf_token %}
		<div clas="form-group">
			<textarea name="content" id="content" rows="15" class="form-control"></textarea>
		</div>
		<input type="submit" value="답변 등록" class="btn btn-primary"/>
	</form>
</div>

→ 화면 확인

HTML5 표준에 맞춰서 변경

  • templates\base.html 파일을 생성
    : 모든 화면에 공통적으로 적용되는 내용 (문서의 틀)
    → 템플릿 파일 구조화
{% load static %}
<!doctype html>
<html lang="ko">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shring-to-fit=no">
    <link rel="stylesheet" type="text/css" href="{% static 'bootstrap.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'style.css' %}">
    <title>Hello, pybo!</title>
</head>
<body>
    {% block content %}
    {% endblock %}
</body>
</html>
  • templates\pybo\question_list.html 질문 목록 템플릿 수정
{% extends 'base.html' %}

{% block content %}
<div class="container my-3">
    <table class="table">
        <thead>
            <tr class="thead-dark">
                <th>번호</th>
                <th>제목</th>
                <th>작성일시</th>
            </tr>
        </thead>
        <tbody>
            {% if question_list %}
                {% for question in question_list %}
                    <tr>
                        <td>{{ forloop.counter }}</td>
                        <td>
                            <a href="{% url 'pybo:detail' question.id %}">
                            {{ question.subject }}
                            </a>
                        </td>
                        <td>{{ question.create_date }}</td>
                    </tr>
                {% endfor %}
            {% else %}
                <tr>
                    <td colspan="3">질문이 없습니다.</td>
                </tr>
            {% endif %}
        </tbody>
    </table>
</div>
{% endblock %}
  • templates\pybo\question_detail.html 질문 상세 템플릿 수정
{% extends 'base.html' %}

{% block content %}
<div class="container my-3">
	<h2 class="border-bottom py-2">{{ question.subject }}</h2>

	<div class="card my-3">
		<div class="card-body">
			<div class="card-text" style="white-space: pre-line;">
				{{ question.content }}
			</div>
			<div class="d-flex justify-content-end">
				<div class="badge badge-light p-2">
					{{ question.create_date }}
				</div>
			</div>
		</div>
	</div>

	<h5 class="border-bottom my-3 py-2">
		{{ question.answer_set.count }}개의 답변이 있습니다.
	</h5>
	{% for answer in question.answer_set.all %}
	<div class="card my-3">
		<div class="card-body">
			<div class="card-text" style="white-space: pre-line;">
				{{ answer.content }}
			</div>
			<div class="d-flex justify-content-end">
				<div class="badge badge-light p-2">
					{{ answer.create_date }}
				</div>
			</div>
		</div>
	</div>
	{% endfor %}

	<form action="{% url 'pybo:answer_create' question.id %}" method="post" class="my-3">
		{% csrf_token %}
		<div clas="form-group">
			<textarea name="content" id="content" rows="15" class="form-control"></textarea>
		</div>
		<input type="submit" value="답변 등록" class="btn btn-primary"/>
	</form>
</div>
{% endblock %}

질문 등록 기능 추가

  • 질문 목록 페이지에 질문 등록 버튼을 추가(question_list.html)
{% extends 'base.html' %}

{% block content %}
<div class="container my-3">
    <table class="table">
        <thead>
            <tr class="thead-dark">
                <th>번호</th>
                <th>제목</th>
                <th>작성일시</th>
            </tr>
        </thead>
        <tbody>
            {% if question_list %}
                {% for question in question_list %}
                    <tr>
                        <td>{{ forloop.counter }}</td>
                        <td>
                            <a href="{% url 'pybo:detail' question.id %}">
                            {{ question.subject }}
                            </a>
                        </td>
                        <td>{{ question.create_date }}</td>
                    </tr>
                {% endfor %}
            {% else %}
                <tr>
                    <td colspan="3">질문이 없습니다.</td>
                </tr>
            {% endif %}
        </tbody>
    </table>
    <!-- 질문 등록 버튼 추가 -->
    <a href="{% url 'pybo:question_create' %}" class="btn btn-primary">
        질문 등록하기
    </a>
</div>
{% endblock %}
  • pybo\urls.py 파일에 URL 매핑을 추가
from django.urls import path
from . import views

app_name = 'pybo'

urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name="detail"),
    path('answer/create/<int:question_id>', views.answer_create, name='answer_create'),
    path('question/create/', views.question_create, name='question_create'),
]
  • pybo\views.py 파일에 question_create 메서드를 추가
from django.shortcuts import render, get_object_or_404, redirect
from .models import Question
from .forms import QuestionForm
from django.utils import timezone

def index(request):
    question_list = Question.objects.order_by('-create_date')
    context = { 'question_list': question_list }
    
    return render(request, 'pybo/question_list.html', context)


def detail(request, question_id): 
    # question = Question.objects.get(id=question_id)
    question = get_object_or_404(Question, pk=question_id)
    context = { 'question': question }

    return render(request, 'pybo/question_detail.html', context)


def answer_create(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    question.answer_set.create(content=request.POST.get('content'), create_date=timezone.now())
    
    return redirect('pybo:detail', question_id=question.id)


def question_create(request):
    form = QuestionForm()
    return render(request, 'pybo/question_form.html', { 'form': form })
  • pybo\forms.py 파일을 생성하고 QuestionForm 클래스를 추가
from django import forms
from pybo.models import Question

class QuestionForm(forms.ModelForm):	 # ModelForm을 상속받아 모델 폼을 정의 
    class Meta:                   # 모델 폼은 Meta라는 내부 클래스를 정의해야 함
        model = Question		  # 모델 폼에서 사용할 모델과 모델의 필드 지정
        fields = ['subject', 'content']
  • templates\pybo\question_form.html 파일 추가
{% extends 'base.html' %}

{% block content %}
<div class="container">
    <h5 class="my-3 border-bottom pb-2">질문 등록</h5>
    <form method="post" class="post-form my-3">
        {% csrf_token %}
        
        # 모델 폼과 연결된 입력 항목(Meta 클래스의 field로 지정된 항목)에
          값을 입력할 수 있는 코드 자동 생성
        {{ form.as_p }}	
        
        <button type="submit" class="btn btn-primary">저장하기</button> 	
    </form>
</div>
{% endblock %}

→ 질문 등록 화면 확인

  • pybo\views.py 파일에 question_create 메서드 수정
    : 요청 방식에 따라서 GET 방식인 경우 입력화면을 반환하고, POST 방식인 경우 내용 저장 후에 리다이렉트 하도록 수정
from django.shortcuts import render, get_object_or_404, redirect
from .models import Question
from .forms import QuestionForm
from django.utils import timezone

def index(request):
    question_list = Question.objects.order_by('-create_date')
    context = { 'question_list': question_list }
    
    return render(request, 'pybo/question_list.html', context)


def detail(request, question_id): 
    # question = Question.objects.get(id=question_id)
    question = get_object_or_404(Question, pk=question_id)
    context = { 'question': question }

    return render(request, 'pybo/question_detail.html', context)


def answer_create(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    question.answer_set.create(content=request.POST.get('content'), create_date=timezone.now())
    
    return redirect('pybo:detail', question_id=question.id)


def question_create(request):
    if request.method == 'GET':
        form = QuestionForm()
        return render(request, 'pybo/question_form.html', { 'form': form })
    elif request.method == 'POST':
        # POST 방식으로 전달된 요청인 경우, 요청 본문을 통해 전달된 입력값을 저장 
        form = QuestionForm(request.POST)
        if form.is_valid():
            question = form.save(commit=False)
            question.create_date = timezone.now()
            question.save()
            return redirect('pybo:index')

→ 질문 등록 동작 확인

  • 질문 입력 화면에 스타일 적용
    : question_form.html 파일에는 {{form.as_p}} 코드를 통해 폼 엘리먼트와 입력 항목을 자동으로 생성해주므로, 스타일을 적용 불가
    → 모델 폼 파일(forms.py)의 Meta 내부 클래스에 widgets과 labels 속성을 이용해서 스타일 적용 가능
from django import forms
from pybo.models import Question

class QuestionForm(forms.ModelForm):
    class Meta:
        model = Question
        fields = ['subject', 'content']
        widgets = {
            # <input type="text" name="subject" maxlength="200" required id="id_subject" class="form-control">
            'subject': forms.TextInput(attrs={'class': 'form-control'}), 
            # <textarea name="content" cols="40" rows="10" required id="id_content" class="form-control">
            'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 10}),
        }
        labels = {
            'subject': '제목', 
            'content': '내용',
        }

애플리케이션 보안

SW 개발보안 가이드
https://www.kisa.or.kr/2060204/form?postSeq=5&lang_type=KO&page=1

SW 보안약점 진단 가이드
https://www.kisa.or.kr/2060204/form?postSeq=9&page=2
Python 시큐어코딩 가이드
https://www.kisa.or.kr/2060204/form?postSeq=13&page=1

JavaScript 시큐어코딩 가이드
https://www.kisa.or.kr/2060204/form?postSeq=14&page=1
모바일 전자정부서비스 앱 소스코드 검증 가이드라인
https://www.kisa.or.kr/2060204/form?postSeq=3&page=2
주요정보통신기반시설 기술적 취약점 분석 평가 상세 가이드
https://www.kisa.or.kr/2060204/form?postSeq=12&page=2
공개SW를 활용한 소프트웨어 개발보안 검증가이드
https://www.kisa.or.kr/2060204/form?postSeq=10&page=3

실습 프로그램 다운로드 및 설정

https://drive.google.com/file/d/1qjAzKSw9sEw6yOaZn1WTD5VR467cl33R/view?usp=sharing
→ WebGoat
https://cdimage.kali.org/kali-2023.4/kali-linux-2023.4-vmware-amd64.7z
→ Kali Linux
https://sourceforge.net/projects/bwapp/files/bee-box/bee-box_v1.6.7z/download
→ bWAPP 가상머신 이미지
https://www.vmware.com/go/getworkstation-win
→ Vmware workstation

다운로드한 프로그램 설치

  1. Vmware Workstation
    : VMware-workstation-full-17.5.1-23298084.exe 설치 (기본 설정을 유지)
    → 아래와 같은 오류가 발생하는 경우, 재부팅 후 Microsoft Visual C++ 2017 Redistributable (x64) Version 14.x 버전을 다운로드해서 설치

  1. WebGoat
    : FullstackLAB_20240312.zip 압축을 C:\ 에 해제
    → 정상적으로 압축을 해제하면 아래와 같은 구조를 가지게 됨

  1. bee-box와 kali-linux
    : bee-box_v1.6.7z 파일과 kali-linux-2023.4-vmware-amd64.7z 파일을 C:\FullstackLAB 폴더 아래에 압축 해제
    → 본인이 원하는 폴더에 압축 해제해도 무관

VMware에 bee-box와 kali-linux 이미지 추가 후 실행

  1. VMware 실행
  2. Open 메뉴에서 위에서 압축 해제한 디렉터리의 이미지를 선택 후 열기 버튼을 클릭

  1. 가상머신 실행

  1. 가상머신 로그인 계정
    : Kali Linux → kali / kali

  2. bee-box 가상머신에서 브라우저를 실행하고 http://localhost/bWAPP로 접속
    : bee-box → bee / bug

  1. bee-box 키보드 변경

각 가상머신의 IP 확인 후 hosts 파일에 등록

  1. kali
┌──(kali㉿kali)-[~]
└─$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.37.128  netmask 255.255.255.0  broadcast 192.168.40.255
        inet6 fe80::403d:144a:a460:bd5b  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:ca:54:d8  txqueuelen 1000  (Ethernet)
        RX packets 103  bytes 16804 (16.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 40  bytes 11528 (11.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 4  bytes 240 (240.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4  bytes 240 (240.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  1. bee-box
bee@bee-box:~$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0c:29:3e:ba:70  
          inet addr:192.168.45.3  Bcast:192.168.40.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe3e:ba70/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:5682 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2263 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:582181 (568.5 KB)  TX bytes:2167508 (2.0 MB)
          Interrupt:16 Base address:0x2024 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:1028 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1028 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:726401 (709.3 KB)  TX bytes:726401 (709.3 KB)
  1. 본인 PC
C:\Users\r2com> ipconfig

Windows IP 구성


이더넷 어댑터 이더넷:					# 유선 네트워크를 사용하고 있는 경우 

   미디어 상태 . . . . . . . . : 미디어 연결 끊김
   연결별 DNS 접미사. . . . :

무선 LAN 어댑터 로컬 영역 연결* 9:

   미디어 상태 . . . . . . . . : 미디어 연결 끊김
   연결별 DNS 접미사. . . . :

무선 LAN 어댑터 로컬 영역 연결* 10:

   미디어 상태 . . . . . . . . : 미디어 연결 끊김
   연결별 DNS 접미사. . . . :

무선 LAN 어댑터 Wi-Fi:

   연결별 DNS 접미사. . . . :
   링크-로컬 IPv6 주소 . . . . : fe80::622c:5a77:1e68:babd%13
   
   # IP가 할당된 무선 LAN 어댑터 확인
   IPv4 주소 . . . . . . . . . : 192.168.45.129
   서브넷 마스크 . . . . . . . : 255.255.255.0
   기본 게이트웨이 . . . . . . : 192.168.0.1

이더넷 어댑터 VMware Network Adapter VMnet1:

   연결별 DNS 접미사. . . . :
   링크-로컬 IPv6 주소 . . . . : fe80::123a:7830:2bb5:3e6e%43
   IPv4 주소 . . . . . . . . . : 192.168.65.1
   서브넷 마스크 . . . . . . . : 255.255.255.0
   기본 게이트웨이 . . . . . . :

이더넷 어댑터 VMware Network Adapter VMnet8:

   연결별 DNS 접미사. . . . :
   링크-로컬 IPv6 주소 . . . . : fe80::a201:eee3:eca8:5fd7%44
   IPv4 주소 . . . . . . . . . : 192.168.40.1
   서브넷 마스크 . . . . . . . : 255.255.255.0
   기본 게이트웨이 . . . . . . :

이더넷 어댑터 Bluetooth 네트워크 연결:

   미디어 상태 . . . . . . . . : 미디어 연결 끊김
   연결별 DNS 접미사. . . . :

C:\Users\r2com>
  1. hosts 파일에 등록할 내용을 작성
    → 앞에서 확인한 본인 환경의 IP 주소를 사용
    kali.linux
    : 192.168.37.128
    bee.box
    : 192.168.45.3
    host.pc
    : 192.168.45.129

  2. 내 PC의 hosts 파일에 4번 내용을 등록 후 저장
    → 관리자 권한으로 명령 프롬프트 실행

C:\Windows\system32> notepad c:\Windows\System32\drivers\etc\hosts

  1. bee-box 가상머신의 hosts 파일에 4번의 내용을 추가 후 저장
bee@bee-box:~$ sudo gedit /etc/hosts
[sudo] password for bee: bug

  1. kali 가상머신의 hosts 파일에 4번의 내용을 추가 후 저장
┌──(kali㉿kali)-[~]
└─$ sudo apt update      

┌──(kali㉿kali)-[~]
└─$ sudo apt install gedit -y

┌──(kali㉿kali)-[~]
└─$ sudo gedit /etc/hosts

실습 종료 후, 가상머신 Suspend 시켜놓기


애플리케이션 보안 / 개발보안 / 시큐어코딩의 필요성

  • 서버와 클라이언트
    : 이 중 서버는 WEB 서버, WAS 서버, DB 서버 등으로 나뉨
  • web 서버는 이미지나 css, js, html 등의 정적(static) 컨텐츠 제공
  • was는 사용자로의 요청을 받아 서버에 프로그램을 실행하여 동적인 컨텐츠를 생성하고 제공해주는 역할
    → web 서버와 was 서버는 같이 동작하는 경우가 많음
    → 처리할 파일이 많아질 경우 웹 서버 하나로는 감당이 안되기 때문에 WAS를 이용해 복잡하거나 많은 로직을 처리

  • 방화벽(F/W)
    : 특정 IP나 port가 들어오거나 나가는 것을 제어

  • 웹 어플리케이션 방화벽(WAF)
    : 들어온 매개변수들의 패턴을 추측하여 보안 관련 공격 방어
    : 요청 헤더나 요청 본문에 있는 문자열을 검사해 해로운 것이 있다면 그것을 막는 역할
    → F/W는 데이터까지는 보지 못하지만 WAF는 볼 수 있음

※ 방화벽과 WAF는 하드웨어를 기반으로 네트워크를 방어하므로 들어오는 공격들을 100% 막기엔 어려움

  • 인증/인가는 방화벽 같은 장비들이 막기는 어려움
    : 그러므로 로그인한 사용자만 게시판 내용을 볼 수 있게 하는 등 애플리케이션에서 이러한 보안 기능을 구현해주는 경우가 대다수
    → 그러나 구현이 안된 경우, 방화벽 같은 장비들로 이것을 막음

  • SW 개발보안 가이드
    → 사전
  • SW 보안약점 진단 가이드
    → 사후
    : 하지만 내용은 거의 일치
    : 자바 언어를 베이스로 설명

※ 침해사고의 대부분은 잘못 만들어진 소스코드에 의해 발생하는 정보 유출 등의 경우가 대다수

  • 호환이 되는지 테스트를 하고 테스트 된 프로그램을 배포하려면 시간이 오래 걸림
    → 문제가 있을 때 해결하려고 하면 많은 비용이 드므로 초기 단계에서 많은 노력을 기울여야 뒤에서 수정할 때 비교적 적은 비용과 적은 노력이 드니 코딩 시 주의를 기울여야 함

  • 시큐어 코딩
    : 소스 코드에 잠재보안 약점을 제거
    : 현재는 문제가 없더라도 나중에 시간이 지나서 문제가 생길 가능성 다분
    코드를 안전하게 하기 위한 기법을 '시큐어 코딩'이라고 함

  • 개발 보안 방법론
    : SW 개발 과정에서 실행되는 일련의 보안 사이클을 수행해야 함

  1. 요구사항 분석
    : 사용자가 원하는 기능을 도출
    : 개발 과정에선 기능 요구사항을 많이 따졌었지만 보안 개발 과정에선 보안 요구사항이 어떻게 만들어져야 하는가에 대해 기술
    → ex. 패스워드는 암호화해서 저장, 패스워드는 일방향 해시 함수를 통해 저장 등

  2. 설계
    : 위험사항이 뭐가 있는지?
    : 그에 관련된 외부 위협 사항이 뭐가 있는지?
    : 각종 위험 요소들과 관련하여 보안에 대해 고려해야하는 것들을 작성

  3. 구현
    : 표준에 맞춰 코딩
    : 교육받은 대로 코딩을 하는지 모니터링도 함
    : 도구를 활용해 보안 약점을 진단하는 방법도 있음
    → 정적분석도구

  4. 테스트
    : 해당 단계에서 문제점이 발견되면 구현 단계, 잘못하면 설계 단계까지 돌아가 다시 해야될 수도 있음
    : 코드의 보안 취약점에 대해 진단하고 그를 테스트

  • 애플리케이션의 문제점을 도출
    → 정적 분석과 동적 분석은 상호 보완적 관계로 항상 함께 적용해야 함
  • 정적 분석
    : 애플리케이션을 실행하지 않고 소스 코드의 내용, 형태, 구문 등을 분석해서 문제가 있는지 확인

    코드 리뷰

    SQL Injection 과 같이 소스 코드 구문을 통해서 확인할 수 있는 문제점을 쉽고, 명확하게 찾을 수 있음
    : ex) cursor.execute(query, (param1, param2, ...))
    → SQL Injection에 안전한 코드
    : ex) cursor.execute(f"select ... where id = {name}")
    → SQL Injection에 취약한 코드
  • 동적 분석
    : 애플리케이션을 실행해서 원하는(계획한) 결과가 제공되는지 확인

    디버깅, 부하테스트, 모의해킹/침투테스트

    인증 및 인가와 같이 정적 분석으로 파악이 힘든 경우 수행
    : ex) 게시판 상세 조회 페이지는 로그인한 사용자만 볼 수 있는지 로그인 전후에 게시판 상세 조회를 해 보면 쉽게 알 수 있음

  • 소프트웨어 보안약점
  1. 입력 데이터 검증 및 표현
    : 가장 많음
    : 가장 기본
    : 문법, 데이터에서 잘못된 것을 찾아낼 수 있는 경우가 많음

  2. 보안 기능
    : 보안과 관련해 잘못 구현했을 때 발생할 수 있음
    : 암호화, 인가, 인증 등

  3. 시간 및 상태
    : 동시성과 관련
    : 멀티 프로세스와 관련해 발생할 수 있는 문제들

  4. 에러 처리
    : 오류가 발생할 수 있음에도 불구하고 예외 처리를 하지 않았을 경우
    : 예외를 두리뭉실하게 처리했을 경우
    : 메시지를 통해 외부로 유출되는 경우

  5. 코드 오류
    : 코딩 오류로 인해 발생할 수 있는 보안 약점

  6. 캡슐화
    : 데이터를 숨기는 것, 포괄적으론 보호해야하는 데이터를 외부에서 알지 못하도록 하는 것
    : 캡슐화가 잘못되어 외부에 내용이 노출되었을 때 이를 캡슐화 오류라고 함

  7. API 오용
    : 사용하면 안되는 API를 사용했거나 잘못 사용한 경우 발생할 수 있는 에러

HTTP(HyperText Transfer Protocol)

HTTP의 특징

: HTTP is simple
: HTTP is extensible
: HTTP is stateless(무상태), but not sessionless
→ 성공적으로 완료된 두 개의 요청 사이에는 연결고리 X
→ 헤더 확장성을 사용하여 동일한 컨텍스트, 동일한 상태를 공유하기 위해 각각의 요청들에 세션을 만들도록 쿠키 추가
: HTTP and connections
→ HTTP/1.0
: 요청/응답 교환에 대한 각각의 TCP 연결 생성
→ HTTP/1.1
: 파이프 라이닝 개념과 지속적인 연결의 개념 도입(기본적인 TCP 연결을 Connection 헤더를 사용해 부분적으로 제어)
→ HTTP/2
: 단일 연결을 통해 메시지 다중화, 연결을 보다 효율적으로 유지

HTTP 흐름

연결 → 요청 → 응답 → 연결해제

  • HTTP 요청
    : 웹 브라우저가 웹 서버에게 자원 요청
    : 시작줄, 요청 헤더, 요청 본문으로 구성
    : 시작줄
    → "요청 방식(method) + URL + 프로토콜 버전" 으로 구성
    : 요청 헤더와 요청 본문 사이에는 1개의 빈 공백 라인 존재

  • HTTP 응답
    : 웹 브라우저의 요청에 대한 처리 결과 전달
    : 시작줄, 응답 헤더, 응답 본문으로 구성
    : 시작줄
    → "프로토콜 버전 + 상태 코드 + 상태 메시지" 로 구성

요청 메서드

  • GET
    : 웹 서버로 자원을 요청할 때 사용(default)
    : 요청 파라미터를 URL에 포함해 전달하는 방식
    : 전송할 수 있는 데이터의 크기 제한
    : 북마크가 필요한 경우 사용

  • POST
    : 웹 서버로 자원 요청 시 사용
    : 요청 파라미터를 요청 본문에 포함해 전달하는 방식
    : 전송할 수 있는 데이터의 크기 제한 X (시간 제한 개념)

0개의 댓글