CORS : Cross-origin resource sharing

 웹 브라우저들은 보안상의 이유로 javascript나 ajax로 외부 host로 접속하는 것을 막기 시작했다. 그래서 javascript를 Same Origin Policy(동일 출처 정책)라는 정책을 두어 다른 도메인의 서버에 요청하는 것을 보안문제로 간주하고 이를 차단한다. javascript는 자신이 속한 동일 도메인 내에서만 서버 요청을 허용하고 처리해 주겠다는 의미이다.



네 가지의 크로스 도메인 문제

1. 도메인은 같으나 서브도메인이 다르면 문제가 발생한다.

  www.xyz.com과 aaa.xyx.com 사이의 문제를 말한다.


2. 도메인이 다르면 문제가 발생한다.

 www.xyz.com과 www.abc.com 사이의 문제를 말한다.


3. 프로토콜이 다르면 문제가 발생한다.

 http에서 https로의 호출은 문제가 발생하지 않지만 https에서 http로의 호출은 문제가 발생한다.


4. 포트번호가 다르면 문제가 발생한다.

 http://zzz.com:8000 / http://zzz.com:8080 사이의 문제를 말한다.



프로토콜로 인한 크로스 도메인 오류 해결

 jsp 개발을 하면서 https에서 http로의 호출에서 크로스 도메인 문제가 발생했다. http에서 ajax로 폼 데이터를 넘기면 https에서 db에 insert를 하고 작성한 javascript를 response로 보내 http에서 실행하는 것이었다. 두 가지 방법의 해결법을 찾았다.


1. http로 접속하면 자동으로 https로 바꿔준다. 즉, 모든 페이지를 https로만 동작하게 한다.

1
2
3
4
5
String url = request.getRequestURL().toString();
if(url.startsWith("http://"&& url.indexOf("localhost"< 0) {
    url = url.replaceAll("http://""https://");
    response.sendRedirect(url);
}
cs


2. https의 jsp 파일에서 response 헤더필드에 Access-Control-Allow-Origin을 추가하여 해결했다.

     - 특정 host 접근 허용

1
Access-Control-Allow-Origin : http://www.xyz.com
cs


         - 모든 접근 허용

1
Access-Control-Allow-Origin : *

cs


모든 접근을 허용하게 되면 보안상의 문제가 발생할 수 있기 때문에 특정 host만 허용하도록 했다.

1
response.addHeader("Access-Control-Allow-Origin", "http://www.xyz.com");
cs




참고 : https://pedaler.github.io/CORS-%ED%81%AC%EB%A1%9C%EC%8A%A4-%EB%8F%84%EB%A9%94%EC%9D%B8-%EC%9D%B4%EC%8A%88%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC/

크로스브라우징의 문제를 해결해준다.

jQuery에서 제공하는 Ajax를 사용하면 여러가지 장점이 있다. 그 중 하나는 브라우저간의 차이점을 jQuery가 알아서 처리해주는 것이다. 즉, 우리가 만든 어플리케이션을 어떤 브라우저를 사용해서 동작하든 간에 동일한 코드를 갖게된다는 것이다.



jQuery는 Ajax와 관련해서 많은 API를 제공한다.

http://api.jquery.com/category/ajax/

위 링크에서 확인할 수 있다.


- Global Ajax Event Handlers

jQuery를 이용해서 Ajax 통신을 할 때 여러 곳에서 Ajax를 사용할 경우 이것들 전체에 글로벌리하게 적용할 수 있는 여러 설정 등을  지정할 수 있는 기능이다. (고급기능!)


- Helper Functions

통신에 직접적으로 관여하는 API는 아니지만 통신을 하는데에 있어서 여러가지 편리한 기능들을 제공한다.

ex) Form 입력 값을 넘길 때 데이터를 하나로 모아주는 Serialize 등이 있다.


- Shorthand Methods

통신을 하는 방식이 무엇이냐에 따라서 더 적은 코드를 작성하면서 해당 기능을 사용할 수 있다.

ex) jQuery.get()은 get방식을 사용하는 것


- Low-Level Interface

위의 방식 말고 이곳에 있는 .ajax() API를 사용하는 것을 추천한다. 가장 기본적인 API이고 이것을 쉽게 사용할 수 있도록 한 것이 위의 방식이다.



jQuery.ajax()

jQuery에서 Ajax를 통해서 통신하는 데에 있어서 가장 근본이 되는 API이며 가장 많이 사용되는 API이다.

생활코딩 강의에서의 주제도 이 API이다.


$.ajax를 사용해서 호출한다. http://api.jquery.com/jQuery.ajax/ 이곳의 예제 코드를 확인하자.



$.ajax의 문법

1
jQuery.ajax( [settings ] )
cs


setting은 Ajax 통신을 위한 옵션을 담고 있는 객체가 들어간다. 주요한 옵션을 살펴보자.


- data

서버로 데이터를 전송할 때 이 옵션을 사용


- dataType

서버측에서 전송한 데이터를 어떤 형식의 데이터로 해석할 것인가를 지정한다. 값으로 올 수 있는 것은 xml, json, script, html이다. 형식을 지정하지 않으면 jQuery가 알아서 판단한다.


- success

성공했을 때 호출한 콜백을 지정한다. Function( PlainObject data, String textStatus, jqXHR jqXHR )


- type

데이터를 전송하는 방법을 지정한다. get, post를 사용할 수 있다.


앞의 게시물의 코드를 이 API를 활용하여 바꿔보면 훨씬 간결해진 것을 알 수 있다.


time.php

1
2
3
4
5
<?php
    $d1 = new DateTime;
    $d1->setTimezone(new DateTimezone($_POST['timezone']));
    echo $d1->format($_POST['format']);
?>
cs


demo.html





POST방식으로 서버와 통신하는 방법


예제 코드를 먼저 살펴보자


time.php

1
2
3
4
5
<?php
    $d1 = new DateTime;
    $d1->setTimezone(new DateTimezone("asia/seoul"));
    echo $d1->format('H:i:s');
?>
cs

demo_post.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax</title>
</head>
<body>
<p>time : <span id="time"></span></p>
<form>
    <select name="timezone">
        <option value="Asia/Seoul">asia/seoul</option>
        <option value="America/New_York">America/New_York</option>
    </select>
    <select name="format">
        <option value="Y-m-d H:i:s">Y-m-d H:i:s</option>
        <option value="Y-m-d">Y-m-d</option>
    </select>
</form>
<input type="button" id="execute" value="execute" />
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
    $('#execute').click(function(){
        $.ajax({
            url:'./time.php',
            type:'post',
            data:$('form').serialize(),
            success:function(data){
                $('#time').text(data);
            }
        })
    })
</script>
</body>
</html>
cs


26번째줄

1
data:$('form').serialize()
cs

이 코드는 form태그의 정보를 값의 이름 = 값의 내용&값 의 형식으로 바꿔준다. 즉, form의 값들을 하나의 텍스트로 만들어주는 것이다.




JSON을 처리하는 방법


time.php

1
2
3
4
<?php
    $timezones = ["Asia/Seoul""America/New_York"];
    echo json_encode($timezones);
?>
cs

두 개의 값을 담고 있는 배열 timezones을 json_enode를 통해서 json타입으로 변환 후 그것을 화면에 출력해준다.



demo_json.html (html 포맷 생략)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<p id="timezones"></p>
<input type="button" id="execute" value="execute" />
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
    $('#execute').click(function(){
        $.ajax({
            url:'./time.php',
            dataType:'json',
            success:function(data){
                var str = '';
                for(var name in data){
                    str += '<li>'+data[name]+'</li>';
                }
                $('#timezones').html('<ul>'+str+'</ul>');
            }
        })
    })
</script>
cs

8번째줄 : time.php가 리턴해주는 데이터가 json형식이라는 것을 명시해줌



자바스크립트를 이용해서 내부적으로 통신할 수 있는 방법이다.


Ajax : Asynchronous JavaScript and XML -> 자바스크립트를 이용해서 비동기적으로 서버와 브라우저가 데이터를 주고 받는 방식을 의미


이 때 사용하는 API가 XMLHttpRequest이다. (IE5,6에서는 XMLHttpRequest 대신 ActiveXObject("Msxml2.XMLHTTP.6.0")을 사용해야 함)

꼭 XML을 사용해서 통신해야 하는 것은 아니다. XML보다 JSON을 더 많이 사용한다.



** Ajax를 실습해보기 위해서는 서버 환경이 구축돼있어야 한다.


demo1.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax</title>
</head>
<body>
<p>time : <span id="time"></span></p>
<input type="button" id="execute" value="execute" />
<script>
    document.querySelector('input').addEventListener('click'function(event){
        var xhr = new XMLHttpRequest();
        xhr.open('GET''time.jsp');
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && xhr.status === 200){
                document.querySelector('#time').innerHTML = xhr.responseText;
            }
        }
        xhr.send();
    });
</script>
</body>
</html>
cs



time.php

1
2
3
4
5
<?php
    $d1 = new DateTime;
    $d1->setTimezone(new DateTimezone("asia/seoul"));
    echo $d1->format('H:i:s');
?>
cs



demo.html을 실행하고 개발자도구로 네트워크를 살펴보자

1. demo.html 실행



2. excute 클릭


php가 아닌 jsp로 만들어버려서 코드가 그대로 나온다. 여기서 살펴볼 것은 time 파일이 호출되는 것이다.

화면의 reload 없이 비동기적으로 데이터만 가져와 뿌려준다.

https의 탄생

http는 html같은 문서를 웹 브라우저가 웹 서버에 요청하는 프로토콜이다. 단순하게 보면 텍스트를 교환하는 것이라고 할 수 있다.

따라서 네트워크 안에서 내가 보낸 텍스트를 누군가가 가로챈다면 그 내용이 그대로 보이게 된다. 예를들어 A가 메일을 읽고 있는 도중에 B가 그 신호를 가로챈다면 B가 A의 메일을 읽을 수 있게 된다.


그래서 나온 것이 https이다.


https는 http + secure로, 공개키 암호화 방식을 사용하여 텍스트를 암호화하는 프로토콜이다.


그렇다면 왜 아직까지 http 방식을 사용하는 사이트가 많을까?

https 암호화를 하면 웹 서버에 부하가 생기기 때문이다. 따라서 우리나라같은 경우 보안이 철저하게 이루어져야 할 금융사이트 등에서 많이 사용한다.





이외의 다른 이유들도 있는데, 아래 링크를 참조하면 좋을 것 같다.


출처 - http://kmj1107.tistory.com/entry/Http-vs-Https-Http%EC%99%80-Https%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90



html의 form에서 submit할 경로를 지정할 때 https 프로토콜을 사용하는 url로 지정하는 것도 가능하다.

이것을 사용하면 폼 자체가 안정하지 않은 페이지에 https를 이용해서 접근하는 곳에 호스트된 경우 데이터는 나머지 요청들과 함께 암호화된다.

반면 만약 폼이 보안 페이지에서 호스트된 경우라도 action 속성에서 안정하지 않은 http url을 지정하면 모든 브라우저는 데이터가 암호화되지 않았기 때문에 데이터를 보낼 때마다 보안 경고를 출력할 것이다.


출처 - https://developer.mozilla.org/ko/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data




페이지 이동

https -> http 의 이동은 문제 없이 가능하지만, http -> https 의 이동은 할 수 없다. 이것은 크로스 도메인의 문제로, 다른 글의 주제로 포스팅했다. 

break는 해당 if문만 종료시키지만, return은 해당 메소드가 호출된 곳까지 종료시킨다. 즉, if문을 포함한 메소드 자체를 종료시킨다.

+ Recent posts