반응형

개발하다가 재기동과 새로고침을 아무리해도 적용이 되지 않는 경우가 있다.

2가지방법을 제안한다.

 

 

1. F12를 눌러보면 개발자 도구가 뜬다. 그 상태에서 새로고침 버튼을 우클릭하면 아래와 같이 된다.

캐시 비우기 및 강력 새로고침 하면 된다~

 

 

2. F12를 누른 후 빨간 네모인 Disable cache 에 체크를 한다.

 

끝.

반응형
반응형

CryptoJS 를 이용한 암호화


CryptoJS 를 사용하면 웹에서도 손쉽게 AES 암호화가 가능하다.


자바스크립트에서 AES 암호화 예 1

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
<script    src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
<script    src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/sha256.js"></script>
<script>
    
//메시지 암호화
    var message = "Led Zeppelin- Stairway to Heaven"
    var passphrase = "1234";
    var encrypt = CryptoJS.AES.encrypt(message, passphrase);
    var decrypted = CryptoJS.AES.decrypt(encrypt, passphrase );
 
    // 암호화 이전의 문자열은 toString 함수를 사용하여 추출할 수 있다.
    var text = decrypted.toString(CryptoJS.enc.Utf8);

//파일 암호화
var formData = new FormData();
var image = $("#img_1").attr('src');
var key = "${map.key}"; //암호화 key
var encrypt = CryptoJS.AES.encrypt(image, key+"<%=session.getId()%>",{ //암호화키 + 세션ID mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }).toString(); formData.append("attach1", encrypt);
//AJAX
$.ajax({ .... });
</script>
cs



자바스크립트에서 AES 암호화 예 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script    src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
<script    src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/sha256.js"></script>
<script>
    
    var message = "Led Zeppelin- Stairway to Heaven"
 
    // 생성된 해쉬 값을 사용하면 평문 사용을 피할 수 있다.
    var hashedPassword = CryptoJS.SHA256("1234").toString() ; 
 
    var encrypt = CryptoJS.AES.encrypt(message, hashedPassword);
    var decrypted = CryptoJS.AES.decrypt(encrypt, hashedPassword );
 
    // 암호화 이전의 문자열은 toString 함수를 사용하여 추출할 수 있다.
    var text = decrypted.toString(CryptoJS.enc.Utf8);
</script>
cs


텍스트 형식의 비밀번호를 사용하고 싶지 않는 경우는 SHA-256 같은 단방향 해쉬 알고리즘을 사용 (암호화된 메시지) 다이제스트를 생성하여 사용할 수 도 있다. 대부분의 웹 프로그램들은 보통 텍스트 형식의 비밀번호를 추론하기 어렵게 단방향으로 암호화하여 비밀번호를 보호하고 있다. (원본 메시지를 알면 암호화된 메시지를 구하기는 쉽지만 암호화된 메시지로는 원본 메시지를 구할 수 없어야 하며 이를 '단방향성'이라고 한다.) 


자바에서 원본 메시지를 구하기 위해서는 CryptoJS 내부적으로 키생성을 위하여 내부적으로 사용하는 비표준 OpenSSL KDF 를 사용함을 알고 있어야 한다. (사실 이미 관련 자바 코드가 공개되어 있어 몰라도 상관없다.) 


주의할 것은 자바에서는 미국 이외의 국가에는 암호화 관련 제약(AES에서 128bit(16byte)를 초과하는 길이의 key 사용불가)이 있으며 별도의 확장 패키지(JCE Unlimited Strength Jurisdiction Policy)를 설치를 통하여 해지가 가능하다. 참고로 SHA-256를 사용하지 않고 PBKDF2 키를 사용하면 확장 패키지 설치 없이 암호화 및 복호화가 가능하다. 

Java SE Downloads 



자바에서 복호화


다음은 자바에서 암호화된 메시지를 복호화하는 과정이다. 




복호화 예제

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
 
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
 
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
 
public class CryptoTest {
    
    public static void main(String[] args) throws UnsupportedEncodingException, GeneralSecurityException, DecoderException {        
        String ciphertext = "U2FsdGVkX18+s94R2PY8hZ+HLrPiucqI33KNQHmkAvES41hGlh1HLgfTwGbwc9dkSid4RW5xj5yBn9hj0y7y0A==";
        String password = "1234";
        System.out.println ( decrypt(ciphertext, password) );
       }
    
    public static String decrypt(String ciphertext, String passphrase) {
        try {
            final int keySize = 256;
            final int ivSize = 128;
 
            // 텍스트를 BASE64 형식으로 디코드 한다.
            byte[] ctBytes = Base64.decodeBase64(ciphertext.getBytes("UTF-8"));
 
            // 솔트를 구한다. (생략된 8비트는 Salted__ 시작되는 문자열이다.) 
            byte[] saltBytes = Arrays.copyOfRange(ctBytes, 816);
            System.out.println( Hex.encodeHexString(saltBytes) );
            
            // 암호화된 테스트를 구한다.( 솔트값 이후가 암호화된 텍스트 값이다.)
            byte[] ciphertextBytes = Arrays.copyOfRange(ctBytes, 16, ctBytes.length);
                       
            // 비밀번호와 솔트에서 키와 IV값을 가져온다.
            byte[] key = new byte[keySize / 8];
            byte[] iv = new byte[ivSize / 8];
            EvpKDF(passphrase.getBytes("UTF-8"), keySize, ivSize, saltBytes, key, iv);
            
            // 복호화 
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
            byte[] recoveredPlaintextBytes = cipher.doFinal(ciphertextBytes);
 
            return new String(recoveredPlaintextBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        return null;
    }
    
    private static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, byte[] resultKey, byte[] resultIv) throws NoSuchAlgorithmException {
        return EvpKDF(password, keySize, ivSize, salt, 1"MD5", resultKey, resultIv);
    }
 
    private static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, int iterations, String hashAlgorithm, byte[] resultKey, byte[] resultIv) throws NoSuchAlgorithmException {
        keySize = keySize / 32;
        ivSize = ivSize / 32;
        int targetKeySize = keySize + ivSize;
        byte[] derivedBytes = new byte[targetKeySize * 4];
        int numberOfDerivedWords = 0;
        byte[] block = null;
        MessageDigest hasher = MessageDigest.getInstance(hashAlgorithm);
        while (numberOfDerivedWords < targetKeySize) {
            if (block != null) {
                hasher.update(block);
            }
            hasher.update(password);            
            // Salting 
            block = hasher.digest(salt);
            hasher.reset();
            // Iterations : 키 스트레칭(key stretching)  
            for (int i = 1; i < iterations; i++) {
                block = hasher.digest(block);
                hasher.reset();
            }
            System.arraycopy(block, 0, derivedBytes, numberOfDerivedWords * 4, Math.min(block.length, (targetKeySize - numberOfDerivedWords) * 4));
            numberOfDerivedWords += block.length / 4;
        }
        System.arraycopy(derivedBytes, 0, resultKey, 0, keySize * 4);
        System.arraycopy(derivedBytes, keySize * 4, resultIv, 0, ivSize * 4);
        return derivedBytes; // key + iv
    }    
}
cs



AES256 복호화의 경우 java 버전마다 깔린곳에 외부 라이브러리를 덮어쓰기 해야한다. 보통 업체쪽에서는 원하지 않고 꺼려하므로 bouncycastle 라이브러리를 사용하여 복호화 하는 방법이 있다. 추후 소스 올릴 예정이다. ^^ 


출처 및 참고 : http://andang72.blogspot.com/2016/12/blog-post.html

반응형
반응형

JSP 개발서버, 스테이징서버, 상용서버를 만지다 보면 외부 API나 라이센스 등등 URL만 바뀌어서 사용하는 경우가 많다.


한번에 바꾸기 위한 방법이다.


1. deploy_domain.jsp


<%

// 상용 // String deploy_domain = "http://real.penthegom.co.kr"; // 스테이징 // String deploy_domain = "http://stage.penthegom.co.kr"; // 개발 // String deploy_domain = "http://dev.penthegom.co.kr"; // 로컬 // String deploy_domain = "http://localhost:8080"; %>

2. 원하는.jsp 사용방법


<%@ include file="/deploy_domain.jsp"%>

...

...

<%

...

if(deploy_domain.indexOf("real") > -1){

...

}else if(deploy_domain.indexOf("stage") > -1){

...

}else if(deploy_domain.indexOf("dev") > -1){

...

}else{

...

}

...

%>

...

...


반응형
반응형

XSS 란?


Cross-site Scripting. 링크 타고 들어갔는데 교차사이트 스크립팅 방지한다고 안 되면 진짜 짜증난다.

SQL injection과 함께[1] 웹 상에서 가장 기초적인 취약점 공격 방법의 일종으로, 악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법을 말한다. 공격에 성공하면 사이트에 접속한 사용자는 삽입된 코드를 실행하게 되며,[2] 보통 의도치 않은 행동을 수행시키거나 쿠키나 세션 토큰 등의 민감한 정보를 탈취한다.

크로스 사이트 스크립팅이란 이름 답게, 자바스크립트를 사용하여 공격하는 경우가 많다. 공격 방법이 단순하고 가장 기초적이지만, 많은 웹사이트들이 XSS에 대한 방어 조치를 해두지 않아 공격을 받는 경우가 많다. 여러 사용자가 접근 가능한 게시판 등에 코드를 삽입하는 경우도 많으며, 경우에 따라서는 메일과 같은 매체를 통해서도 전파된다. 

물론, HTML을 사용하는 것이기 때문에, Text-Only 게시판이나, BBCode를 이용하는 위키위키 등에서는 XSS가 발생할 일은 없다. 단, 나무위키의 경우 {{{#!html HTML}}} 을 이용해서 HTML 태그를 사용할 수 있으므로 취약점이 있을 수도 있다. 그래서 나무위키 초반에는 스크립트 태그와 이벤트 속성도 막지 않았다. 물론, 이는 후에 대부분 수정되었다.

주로 CSRF를 하기 위해서 사용되기 때문에 종종 CSRF와 혼동되는 경우가 있으나, XSS는 자바스크립트를 실행시키는 것이고, CSRF는 특정한 행동을 시키는 것이므로 다르다.



3.1. 스크립트 태그[편집]

방법

스크립트 태그로 자바스크립트를 실행한다.

예제

<script>alert('XSS');</script>

설명

스크립트 태그의 스크립트를 실행시킨다. 안타깝게도, 매우 정직한 방법이라 대부분의 사이트에서 막는 경우가 많다. 브라우저단에서 필터링 해주는 경우도 있다. 물론 예외도 있다.[5] 하지만 만들어진지 몇십 년 이상 되었거나, 보안 X까! 하면서 막지도 않는 경우도 있다. 애초에 비밀번호를 평문/MD5로 저장하는 경우도 있는데 새삼스럽게...

3.2. 자바스크립트 링크[편집]

방법

링크 태그로 자바스크립트를 실행한다.

예제

<a href="javascript:alert('XSS')">XSS</a>

설명

브라우저에서 about: 링크와 같이, javascript: 로 시작하는 링크는 스크립트를 실행시킨다. 스크립트 태그와 같이, javascript: 를 필터링하는 경우가 많아 많은 사이트에서 막는다.

3.3. 이벤트 속성[편집]

방법

이벤트 속성을 사용한다.

예제

<img src="#" onerror="alert('XSS')">

설명

이벤트 속성으로 스크립트를 실행할 수 있다. 주로 on 으로 시작하는 속성이 이벤트 속성이다. 자주 사용되는 이벤트 속성으로는 onload onerror onclick 등이 있다. 물론, 이 방법 역시 '자바스크립트 링크' 방법만큼 많이 막혔다.

3.4. 블랙리스트 우회[편집]

방법

알려지지 않은 태그와 속성들을 사용한다.

예제

<ruby oncopy="alert('XSS')">XSS</ruby>

설명

블랙 리스트 방식으로 막는 사이트에 사용할 수 있다. 이벤트 속성 목록을 참고하자. 위의 방법들보다는 적게 막혔으나, 여전히 최근 웹사이트들에선 화이트리스트 방식 차단이 대부분이라, 막혔을 가능성이 높다.

3.5. 내용 난독화[편집]

방법

따옴표로 감싸는 문자열 사이에 공백 문자들을 넣고, HTML 인코드를 하여 난독화한다.

예제

<a href="&#x6A;&#x61;&#x76;&#x61;&#x73;&#xA;&#x63;&#x72;&#x69;&#x70;&#x74;&#xA;&#x3A;&#xA;&#x61;&#x6C;&#x65;&#x72;&#x74;&#xA;&#x28;&#x27;&#x58;&#x53;&#x53;&#x27;&#x29;">XSS</a>

설명

일부 브라우저에서 javascript: 링크 사이에 공백 문자가 들어갈 수 있고, HTML 인코드를 해도 디코드된 내용이 출력된다는 점을 이용한다. 여기에서는 '자바스크립트 링크' 방법과 사용하였지만, 당연히 다른 방법과 함께 사용할 수 있다.

-나무 위키 발췌-



위와 같이 공격할 수 있다는 내용이다.

필자는 Spring-Boot를 사용하기 때문에 적용방법을 적어보자 한다.


naver에 lucy-xss-servlet-filter를 적용하고자 한다.

깃헙 주소 : https://github.com/naver/lucy-xss-servlet-filter


먼저 pom.xml에 디펜던시를 추가하거나 jar 파일을 받아 라이브러리 빌드패스에 추가한다.

<dependency>
	<groupId>com.navercorp.lucy</groupId>
	<artifactId>lucy-xss-servlet</artifactId>
	<version>2.0.0</version>
</dependency>



%%% 주의 사항 %%%

프로젝트 중 소켓통신이나 json데이터가 있을경우 json데이터 안에 있는 xss필터링 문자열도 걸러내는 경우가 생긴다. 해당 글은 이것을 해결하고 올린 글이다.




먼저 spring-boot의 핵심인 빈을 추가한다. XssServletFilter 클래스는 아래에 나온다.


1. WebMvcConfig.java


@Configuration

public class WebMvcConfig extends WebMvcConfigurerAdapter 

...

...

import 관련

org.springframework.boot.web.servlet.FilterRegistrationBean

org.springframework.boot.web.servlet.FilterRegistrationBean.FilterRegistrationBean()

 /*

     * lucy-xss-filter

     *  

     * */

    @Bean

    public FilterRegistrationBean getFilterRegistrationBean(){

        FilterRegistrationBean registrationBean = new FilterRegistrationBean();

        registrationBean.setFilter(new XssServletFilter(acceptUrls));

        registrationBean.setOrder(1);

        registrationBean.addUrlPatterns("/*");

        return registrationBean;

    }

...

...



2. XssServletFilter.java


import java.io.IOException;


import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;


import org.slf4j.Logger;

import org.slf4j.LoggerFactory;


import com.navercorp.lucy.security.xss.servletfilter.XssEscapeFilter;

import com.navercorp.lucy.security.xss.servletfilter.XssEscapeServletFilterWrapper;


public class XssServletFilter implements Filter {

private static final Logger logger = LoggerFactory.getLogger(XssServletFilter.class);

private String[] acceptUrls;

public XssServletFilter(String[] acceptUrls){

this.acceptUrls = acceptUrls;

}

private XssEscapeFilter xssEscapeFilter = XssEscapeFilter.getInstance();


@Override

public void init(FilterConfig filterConfig) throws ServletException {

}


@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

if(excludeUrl(request)){

chain.doFilter(request, response); //걸러내는 URI일 경우 요청값 그대로 처리

}else{

chain.doFilter(new XssEscapeServletFilterWrapper(request, xssEscapeFilter), response);

}

}


private boolean excludeUrl(ServletRequest request) {

String uri = ((HttpServletRequest) request).getRequestURI().toString().trim();

logger.info("XssServletFilter Uri : {}", uri);

boolean returnValue = false;

for(String url : this.acceptUrls) {

if(uri.startsWith(url)){

returnValue = true;

}

}

return returnValue;

}


@Override

public void destroy() {

}

}

3. lucy-xss-servlet-filter-rule.xml


src/main/resources 에 넣어야함.


<?xml version="1.0" encoding="UTF-8"?>


<config xmlns="http://www.navercorp.com/lucy-xss-servlet">

    <defenders>

        <!-- XssPreventer 등록 -->

        <defender>

            <name>xssPreventerDefender</name>

            <class>com.navercorp.lucy.security.xss.servletfilter.defender.XssPreventerDefender</class>

        </defender>


        <!-- XssSaxFilter 등록 -->

        <defender>

            <name>xssSaxFilterDefender</name>

            <class>com.navercorp.lucy.security.xss.servletfilter.defender.XssSaxFilterDefender</class>

            <init-param>

                <param-value>lucy-xss-sax.xml</param-value>   <!-- lucy-xss-filter의 sax용 설정파일 -->

                <param-value>false</param-value>        <!-- 필터링된 코멘트를 남길지 여부, 성능 효율상 false 추천 -->

            </init-param>

        </defender>


        <!-- XssFilter 등록 -->

        <defender>

            <name>xssFilterDefender</name>

            <class>com.navercorp.lucy.security.xss.servletfilter.defender.XssFilterDefender</class>

            <init-param>

                <param-value>lucy-xss.xml</param-value>    <!-- lucy-xss-filter의 dom용 설정파일 -->

                <param-value>false</param-value>         <!-- 필터링된 코멘트를 남길지 여부, 성능 효율상 false 추천 -->

            </init-param>

        </defender>

    </defenders>


    <!-- default defender 선언, 필터링 시 지정한 defender가 없으면 여기 정의된 default defender를 사용해 필터링 한다. -->

    <default>

        <defender>xssPreventerDefender</defender>

    </default>


    <!-- global 필터링 룰 선언 -->

    <global>

        <!-- 모든 url에서 들어오는 globalParameter 파라메터는 필터링 되지 않으며

                또한 globalPrefixParameter1로 시작하는 파라메터도 필터링 되지 않는다.

                globalPrefixParameter2는 필터링 되며 globalPrefixParameter3은 필터링 되지 않지만

                더 정확한 표현이 가능하므로 globalPrefixParameter2, globalPrefixParameter3과 같은 불분명한 표현은 사용하지 않는 것이 좋다. -->

        <params>

<!--             <param name="JSONDS1" useDefender="false" /> -->

        </params>

    </global>

    <!-- url 별 필터링 룰 선언 -->

    <url-rule-set>

        <!-- url disable이 true이면 지정한 url 내의 모든 파라메터는 필터링 되지 않는다. -->

<!--         <url-rule> -->

<!--             <url disable="true">/eform/Clip.jsp</url> -->

<!--             <url disable="true">/ajax/eformUserData</url> -->

<!--         </url-rule> -->

    </url-rule-set>

</config>

4. application.properties


xss필터를 타지 않게 할 url 설정 


#xss accept uri 

xss.acceptUrls = /test, /admin


반응형
반응형

웹 사이트 개발 시, 주요한 이슈중의 하나를 꼽자면 크로스 도메인(Cross Domain)이 있습니다.

 

최근 대부분의 웹 브라우저는 Javascript(JQuery)를 이용하여 AJAX 등을 통해서 다른 도메인의 서버의 URL 을 호출하여 데이터를 가져오는 경우, 보안 문제를 발생시킵니다.

 

만약 우리 웹 서비스에서만 사용하기 위해 다른 서브 도메인을 가진 API 함수를 제공하는 API 서버를 구축하였는데, 다른 웹 서비스에서 이 API 서버에 접근하여 마음대로 API를 호출하여 사용한다면 문제가 되겠죠.

 

그래서 Javascript 는 동일 출처 정책(Same Origin Policy) 라는 정책을 두어 다른 도메인의 서버에 요청하는 것을 보안 문제로 간주하고 이를 차단합니다. 즉, Javascript는 자신이 속한 동일한 도메인 내에서만 서버 요청을 허용하고, 처리해주겠다는 것인데요. 이것은 www.ozit.co.kr 도메인에서 호출된 AJAX는 www.ozit.co.kr 도메인 내에 있는 URL만을 호출할 수 있다는 의미입니다. 다시말하면 www.ozit.co.kr 도메인에서 www.tistory.com 의 URL을 AJAX로 호출할 수 없다는 의미이죠.

 

이를 다른 말로는 샌드박스(Sandbox)라고도 합니다. 샌드박스는 보호된 영역 안에서만 프로그램을 동작시킬 수 있도록 하며, 외부에 의해 영향을 받지 않도록 하는 모델을 말하는데요. 이 말뜻은 단어에서 유추할 수 있듯이 어린아이들이 뛰어놀 때, 다치지 않고, 그 안에서만 놀 수 있도록 만든 '모래 놀이통'에서 왔습니다.

 

그런데, 하나의 도메인을 가진 웹 서버에서 모든 처리를 하기에는 효율성이나 성능 등 여러 문제로 각 기능별도 여러 서버를 두는 경우가 많은데요. (API 서버, WAS 서버, 파일(이미지) 서버 등등)

물리적으로 분리된 서버이고, 다른 용도로 구축된 서버이니, 당연히 각각 다른 도메인을 가진 서버들일 텐데, 서로간에 AJAX 통신을 할 수 없는 것일까요? 즉, 서로 다른 도메인간의 호출을 의미하는 크로스 도메인 문제를 해결할 수는 없는 것일까요?

(물리적으로 동일한 서버에서도 여러 도메인을 사용할 수 있는데, 이 때에도 동일하게 크로스 도메인 이슈는 발생합니다. 크로스 도메인은 물리적인 서버나 환경의 이슈가 아닌 도메인 이름 자체의 이슈입니다.)

 

참고로 아래에서 설명드릴 방식은 서버측에서 크로스 도메인을 허용하여 문제를 해결하는 방식인데, 서버의 수정 없이 클라이언트 단에서 이를 해결하는 방법 또한 있습니다. 하지만 100% 해결은 불가능합니다. jsonp, document.domain 값 설정, 크롬 브라우저의 특수 옵션 사용 등 몇몇 방법이 있으나, 범용적인 웹 서비스에서 사용이 어렵거나(사용자가 직접 세팅해야 한다거나), 그 기능이 제한적인 경우가 대부분입니다. 실제 서버에서 해결해주는 것이 표준화된 방법이고, 100% 해결 가능한 방법입니다.

 

 

아래는 크로스 도메인 문제가 발생하면 뜨는 오류 메시지입니다.

 

 

XMLHttpRequest cannot load http://www.ozit.co.kr
No 'Access-Control-Allow-Origin' header is present on the requested resource
.
Origin 'http://abc.ozit.co.kr' is therefore not allowed access.

 

 

 

 

 

 

AJAX는 자원 요청시 XMLHttpRequest 를 통해서 처리되기 때문에 위와 같은 오류가 표시되었습니다.

 

 http://abc.ozit.co.kr 도메인의 웹 서비스에서 http://www.ozit.co.kr 도메인으로 AJAX 호출을 하였으나, 접근할 수 없다는 말입니다.

XMLHttpRequest는 http://www.ozit.co.kr 을 불러올 수 없는데, 그 이유가 Access-Control-Allow-Origin 헤더가 요청된 자원(http://www.ozit.co.kr)에 존재하지 않기 때문이라는데요.

 

파이어폭스로 보는 경우, 좀 더 자세한 한글로 된 안내를 보실 수 있는데요.

"교차 원본 요청 차단: 동일 출처 정책으로 인해 http://www.ozit.co.kr 에 있는 원격 자원을 읽을 수 없습니다. 자원을 같은 도메인으로 이동시키거나 CORS를 활성화하여 해결할 수 있습니다." 라고 합니다.

 

같은 도메인을 사용한다면 당연히 문제가 해결되겠지만, 그러지 못하는 경우라면 CORS를 활성화 시키면 되겠군요.

CORS를 간단히 설명드리자면 Cross-Origin Resource Sharing 의 약자이며, 웹 페이지의 제한된 자원을 외부의 도메인에서의 요청(접근)을 허용해주는 매커니즘입니다. CORS는 브라우저와 서버간의 Cross-Origin 요청을 허용할지 안할지에 대한 여부를 안전하게 결정하도록 상호작용할 수 있는 방법을 정의합니다.

 

 

참고 : CORS (Cross-origin resource sharing)

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

 

 

설명이 이것저것 잡다하게 많은데요, 실제 이를  해결하는 방법은 어렵지 않습니다.

크로스 도메인 요청을 허용할 웹 서버에서 크로스 도메인 이슈를 문제 삼지 않을 도메인을 지정해주면 됩니다.

 

들어오는 모든 요청에 대해 처리해주기 위해 Filter 를 하나 만들어야 될 것 같습니다.

필터(Filter) 이름은 SimpleCORSFilter 로 하기로 하고 SimpleCORSFilter class 를 Filter interface를 구현하여, 생성하도록 합니다.

그리고 이 필터를 웹서비스의 web.xml 에 등록하여 줍니다.

 

 

- web.xml -

<filter>
    <filter-name>cors</filter-name>
    <filter-class>com.company.project.util.domain.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>cors</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

 

 

 필터 이름은 cors이며, com.company.project.util.domain 패키지 내에 SimpleCORSFilter 클래스를 구현하였습니다.

 모든 URL 패턴(/*)에 대해 필터가 적용되도록 하였습니다.

 

 

 

- SimpleCORSFilter.java -

 

package com.company.project.util.domain;

 

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;

 

@Component
public class SimpleCORSFilter implements Filter {
 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) res;


        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        
        response.setHeader("Access-Control-Allow-Origin", "*");

     


        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}

 

위의 필터는 web.xml 에 정의한 URL 패턴에 의해서 이 웹 서버로 오는 모든 요청이 이 메서드를 지나치게 됩니다. 이 메서드를 한 번 지나고 나면 결과를 내려받는 HTML 페이지 Header에 Access-Control 과 관련된 4개의 라인이 추가되게 됩니다.

 

* response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");

 - POST, GET, OPTIONS, DELETE 요청에 대해 허용하겠다는 의미입니다.

 

* response.setHeader("Access-Control-Max-Age", "3600");
 - HTTP Request 요청에 앞서 Preflight Request 라는 요청이 발생되는데, 이는 해당 서버에 요청하는 메서드가 실행 가능한지(권한이 있는지) 확인을 위한 요청입니다. Preflight Request는 OPTIONS 메서드를 통해 서버에 전달됩니다. (위의 Methods 설정에서 OPTIONS 를 허용해 주었습니다.)

 여기서 Access-Control-Max-Age 는 Preflight request를 캐시할 시간입니다. 단위는 초단위이며, 3,600초는 1시간입니다. Preflight Request를 웹브라우저에 캐시한다면 최소 1시간동안에는 서버에 재 요청하지 않을 것입니다.

 

* response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
 이는 표준화된 규약은 아니지만, 보통 AJAX 호출이라는 것을 의미하기 위해 비공식적으로 사용되는 절차입니다. JQuery 또한 AJAX 요청 시, 이 헤더(x-requested-with)를 포함하는 것을 확인하실 수 있습니다. 여기서는 이 요청이 Ajax 요청임을 알려주기 위해 Header 에 x-request-width를 설정합니다. Form을 통한 요청과 Ajax 요청을 구분하기 위해 사용된 비표준 규약지만, 많은 라이브러리에서 이를 채택하여 사용하고 있습니다. (참고로 HTML5 부터는 Form 과 Ajax 요청을 구분할 수 있는 Header가 추가되었습니다.)

 

* response.setHeader("Access-Control-Allow-Origin", "*");
 이 부분이 가장 중요한 부분입니다. * 는 모든 도메인에 대해 허용하겠다는 의미입니다. 즉 어떤 웹사이트라도 이 서버에 접근하여 AJAX 요청하여 결과를 가져갈 수 있도록 허용하겠다는 의미입니다.

 만약 보안 이슈가 있어서 특정 도메인만 허용해야 한다면 * 대신 특정 도메인만을 지정할 수 있습니다.

 

 

response.addHeader("Access-Control-Allow-Origin", "*");

 

대신 

 

response.addHeader("Access-Control-Allow-Origin", "http://www.ozit.co.kr");
response.addHeader("Access-Control-Allow-Origin", "http://abc.ozit.co.kr");
response.addHeader("Access-Control-Allow-Origin", "http://test.ozrank.co.kr");

 

 

이렇게 쓰면

 

www.ozit.co.kr, abc.ozit.co.kr, test.ozrank.co.kr 이렇게 3개의 도메인에 대해서만 크로스 도메인을 허용하겠다는 의미입니다.

 

 



출처: http://ooz.co.kr/232 [이러쿵저러쿵]

반응형
반응형

Tomcat의 로그파일중 catalina.out은 하나의 파일에 계속 로그가 누적됨으로

파일의 크기가 무지막지하게 커지는 현상을 볼수있다.

차후 파일의 크기가 일정크기를 벗어났을때 에러도 발생하기때문에 정기적으로 Tomcat을 내리고 삭제해주는 작업을 해야되는

불편함이 있어서 파일을 다른 로그처럼 날짜별로 생성하고 싶었다.


그래서 검색을 했더니 log4j나 몇가지 다른 방법으로 설정하는 방법이 존재하는거 같았다.

하지만 Apache의 rotatelogs를 이용하는게 제일 쉽고 간단해 보였다.


방법은 /Tomcat설치폴더/bin/catalina.sh 파일의 내용중

  shift

  touch "$CATALINA_OUT"

  if [ "$1" = "-security" ] ; then

    if [ $have_tty -eq 1 ]; then

      echo "Using Security Manager"

    fi

    shift

    eval "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \

      -Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \

      -Djava.security.manager \

      -Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \

      -Dcatalina.base="\"$CATALINA_BASE\"" \

      -Dcatalina.home="\"$CATALINA_HOME\"" \

      -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \

      org.apache.catalina.startup.Bootstrap "$@" start \

      >> "$CATALINA_OUT" 2>&1 "&"

  else

    eval "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \

      -Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \

      -Dcatalina.base="\"$CATALINA_BASE\"" \

      -Dcatalina.home="\"$CATALINA_HOME\"" \

      -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \

      org.apache.catalina.startup.Bootstrap "$@" start \

      >> "$CATALINA_OUT" 2>&1 "&"

  fi

이부분에서 몇가지 부분을 아래와 같이 변경한다.

  shift

  #touch "$CATALINA_OUT"

  if [ "$1" = "-security" ] ; then

    if [ $have_tty -eq 1 ]; then

      echo "Using Security Manager"

    fi

    shift

    eval "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \

      -Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \

      -Djava.security.manager \

      -Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \

      -Dcatalina.base="\"$CATALINA_BASE\"" \

      -Dcatalina.home="\"$CATALINA_HOME\"" \

      -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \

      org.apache.catalina.startup.Bootstrap "$@" start \

      2>&1 "&" | /apache설치위치/bin/rotatelogs "$CATALINA_OUT"-%Y-%m-%d 86400 540 &

  else

    eval "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \

      -Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \

      -Dcatalina.base="\"$CATALINA_BASE\"" \

      -Dcatalina.home="\"$CATALINA_HOME\"" \

      -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \

      org.apache.catalina.startup.Bootstrap "$@" start \

      2>&1 "&" | /apache설치위치/bin/rotatelogs "$CATALINA_OUT"-%Y-%m-%d 86400 540 &

  fi

위의 빨간색 글자부분이 변경된 부분이다.

우선 touch "$CATALINA_OUT" 부분을 주석처리한다.

주석처리하지 않으면 아래와같이 파일크기가 0인 catalina.out 이라는 파일이 계속 생성되어 있는것을 볼수 있다.

그다음으로 Apache가 설치된 경로를 확인한다.

이는 날짜별 파일 생성을 위해 rotatelogs를 사용하는데 Apache의 설치경로 아래에 bin폴더에 존재하기 때문이다.

그리고 나서

>> "$CATALINA_OUT" 2>&1 "&" 

부분이 두군데 있는데 두군데 모두를 

2>&1 "&" | /apache설치위치/bin/rotatelogs "$CATALINA_OUT"-%Y-%m-%d 86400 540 &

로 변경해준다.


당연히 "apache설치위치"는 실제 위치를 기재해야된다.

그리고 뒷쪽의 옵션이 %Y-%m-%d 86400 540 이렇게 붙는데

%Y-%m-%d는 날짜 표현(상세 표현 방법은 아래 표 참조)

%A

(지역화된) 완전한 요일 이름

%a

(지역화된) 3-문자 요일 이름

%B

(지역화된) 완전한 달 이름

%b

(지역화된) 3-문자 달 이름

%c

(지역화된) 날짜와 시간

%d

2-자리 일

%H

2-자리 시간 (24 시간 시계)

%I

2-자리 시간 (12 시간 시계)

%j

3-자리 날짜수

%M

2-자리 분

%m

2-자리 달

%p

(지역화된) 12 시간 시계의 am/pm

%S

2-자리 초

%U

2-자리 주일수 (주의 첫번재 날은 일요일)

%W

2-자리 주일수 (주의 첫번재 날은 월요일)

%w

1-자리 요일수 (주의 첫번째 날은 일요일)

%X

(지역화된) 시간

%x

(지역화된) 날짜

%Y

4-자리 연도

%y

2-자리 연도

%Z

시간대 이름

%%

문자그대로 `%'

86400는 로테이션 시간을 초단위로 표현 (86400은 24시간 즉 매일)

540은 표준시와 한국시간과의 시간차를 표현


이제 catalina.out 로그는 날짜별로 생성되어 진다.

아래 참고사이트에 가면 더 다양한 설정 방법 및 옵션을 확인 가능하다.

참고 사이트 : http://adminid.kr/unixlinux/102231

                  http://httpd.apache.org/docs/current/programs/rotatelogs.html



출처: http://savour.tistory.com/316 [사랑향기-아이들의 키만큼 커져가는 행복(서진연)]

반응형
반응형


 나는 개발할 때 Chrome 개발자도구의 console을 굉장히 자주 사용하는데(대부분의 개발자들이 그럴 것이라 생각한다), 오늘은 크롬 개발자도구의 편리한 기능과 잘 쓰진 않지만 알아두면 좋은 기능들을 한 번 정리해 보고자 한다.

Console Open

  • Windows / Linux: Ctrl+Shift+J
  • Mac: Cmd+Opt+J
  • 개발자 도구가 열린 상태: ESC

Console Clear

  • clear() 입력
  • Ctrl+L

Log Options

 console 오른쪽 상단위 톱니바퀴를 누르면 옵션을 볼 수 있다. 주로 사용하는 기능은 다음과 같다.

  • Hide network: 404 또는 500 오류 등은 보여주지 않는다.
  • Log XMLHttpRequst: XML Request를 기록
  • Preserve log: refresh나 탐색하는 동안 log기록을 유지
  • Show timestamps: log행 마다 timestamp를 보여 준다.


그룹화하여 console message 출력하기

 console.group(),  console.groupEnd() 명령어를 사용하면 메세지들을 그룹화 하여 보여줄 수 있다. 또한 이 그룹들은 중첩도 가능하다. 또 그룹이 축소된 상태로 보이게 하고 싶다면 console.group()대신 console.Collapsed()를 사용할 수도 있다.

특정 상황에서만 console message 출력하기

 console.assert()를 사용하면 첫번째 매개변수가 false일때만 두번째 매개변수를 출력한다.

CSS로 출력 스타일 변경하기

 %c와 css style을 이용하면 출력되는 색이나 글자 크기를 바꿀 수 있다.

DOM Element를 Javascript 객체로 나타내기

 console로 DOM Element를 출력해보면 보통 다음과 같이 HTML 형식으로 표현되는 것을 볼 수 있다.

 그러나 개발하다보면 해당 element의 속성을 보고싶은 경우가 있는데 이때 console.dir()를 사용하면 해당 element를 javascript객체로 표현해준다.

객체 정보를 표로 보기

 object나 배열을 console.table()을 사용하면 표로 볼 수 있다.

실행 시간 측정 하기

 console.time()과 console.timeEnd()를 사용하면 실행하는데 걸린 시간을 표시해준다. 따로 new Date() 함수등을 사용할 필요가 없어 편리하다.

$_

 $_를 사용하면 가장 마지막으로 사용했던 selector나 평가식을 반환하다.

Shortcut Selector

 console에서 DOM Element를 선택할때 단축 선택자를 사용할 수 있다. 단축 선택자는 세 종류가 있다.

  • $(): 일치하는 첫 번째 요소를 반환, document.querySelector()와 같다.
  • $$(): 일치하는 모든 요소의 배열을 반환, document.querySelectorAll()과 같다.
  • $x(): Xpath와 일치하는 요소의 배열을 반환한다.
  • $0-4: console에서는 마지막으로 불러왔던 요소 5개를 저장해둔다. 가장 최신은 $0, 가장 오래된 항목은 $4이다.

이벤트가 발생 했을 때 콘솔을 출력하고 싶을 때

 monitorEvents(element, eventType)을 사용하면 특정 이벤트가 발생 했을 때 coonsole에 보여줄 수 있다. unmonitorEvents(element)를 사용하면 이벤트 수신을 해제한다. 또 특정 객체에 연결되어있는 eventListener들을 보고싶다면 getEventListeners(element)를 사용하면 된다.

객체를 클립보드에 복사하기

 copy(object)를 사용하면 지정된 객체의 문자열 표현을 클립보드에 복사할 수 있다.

특정 함수가 호출 되었을 때 디버그 실행하기

 debug(function)을 사용하면 해당 함수가 실행되었을때 sources 패널 내부에서 단계적으로 디버그를 할 수 있도록 해준다.

함수에 전달된 인수를 보고 싶을 때

 monitor(function) 함수를 실행하면 지정된 함수가 실행 되었을 때 함수 이름과 인수를 출력해준다.

ES6 Template literals 응용하기

 chrome은 대부분의 ES6 문법을 지원하기 때문에 template literals를 그대로 사용할 수 있는데, console.log와 조합하면 꽤나 편리하게 사용이 가능하다. 특히 문자열과 변수를 함께 사용해야하는 경우 편리하다. 예를 들어보자. 보통 문자열 중간에 변수 값을 표현하려면 다음과 같이 많이 사용한다.

 template literals은 ``(backtick)과 ${object}를 사용하여 표현할 수 있다. 따라서 다음과 같이 console.log()에 다음과 같이 표현할 수 있다.



출처: http://dev-momo.tistory.com/entry/알마두면-쓸만한-Chrome-Console-기능 [Programming Note]

반응형
반응형

- HTTP 에서 에러가 발생하면 해당 에러와 관련 에러 코드를 발생한다.


이 많은 에러들을 다 알고 있을 필요는 없지만 이번에는 이 에러 코드를 정리해 해보겠다.


- 주로 많이 발생하는 에러는 404, 500 에러 이다.




 HTTP 

에러코드

 에러 메시지 

100

 Continue 

101 

 Switching Protocols

200

 OK, 에러 없이 전송 성공 

202 

 Accepted, 서버가 클라이언트의 명령을 받음 

203 

 Non-authoritative Information, 서버가 클라이언트 요구 중 일부만 전송함 

204 

 Non Content, 클라이언트 요구를 처리했으나 전송할 데이터가 없음 

205 

 Reset Content 

206 

 Partial Content 

300 

 Multiple Choices, 최근에 옮겨진 데이터를 요청함. 

301 

 Moved Permanently, 요구한 데이터를 변경된 임시 URL에서 찾음 

302 

 Moved Permanently, 요구한 데이터가 변경된 URL에 있음 

303 

 See Other, 요구한 데이터를 변경하지 않았기 때문에 문제가 있음 

304 

 Not modified 

305 

 Use Proxy 

400 

 Bad Request, 요청 실패 - 문법상 오류가 있어서 서버가 요청 사항을 이해하지 못함. 

401.1 

 Unauthorized, 권한 없음 - 접속 실패, 이 에러는 서버에 로그온 하려는 요청 사항이 서버에 들어있는 권한과 비교했을 시 맞지 않을 경우 발생. 이 경우, 요청한 자원에 접근할 수 있는 권한을 부여받기 위해서 서버 운영자에게 요청해야 함. 

401.2 

 Unauthorized, 권한 없음 - 서버 설정으로 인한 접속 실패, 이 에러는 서버에 로그온 하려는 요청사항이 서버에 들어있는 권한과 비교했을 때 맞지 않을 경우 발생. 이것은 일반적으로 적절한 www-authenticate head field를 전송하지 않아서 발생함. 

402.3 

 Unauthorized, 권한 없음 - 자원에 대한 ACL에 기인한 권한 없음. 이 에러는 클라이언트가 특정 자원에 접근할 수 없을 때 발생. 이 자원은 페이지가 될 수도 있고, 클라이언트의 주소 입력란에 명기된 파일일 수도 있다. 또한, 클라이언트가 해당 주소로 접속할 때 이용되는 

또 다른 파일일 수도 있다. 접근할 전체 주소를 다시 확인해 보고 웹 서버 운영자에게 여러분이 자원에 접근할 권한이 있는지를 확인한다. 

401.4 

 Unauthorized, 권한 없음 - 필터에 의한 권한 부여 실패. 이 에러는 웹 서버가 서버에 접속하는 사용자들을 확인하기 위해 설치한 필터 프로그램이 있음을 의미함. 서버에 접속하는데 이용되는 인증 과정이 이런 필터 프로그램에 의해 거부된 것임 

404.5 

 Unauthorized, 권한 없음 - ISA PI/CGI 어플리케이션에 의한 권한 부여 실패. 이 에러는 이용하려는 웹 서버의 어드레스에 ISA PI나 CGI 프로그램이 설치되어 있어 사용자의 권한을 검증함. 서버에 접속하는데 이용되는 인증 과정이 이 프로그램에 의해 거부됨. 

402 

 Payment Required, 예약됨 

403.1 

 Forbidden, 금지 - 수행 접근 금지. 이 에러는 CGI나 ISA-PI, 혹은 수행시키지 못하도록 되어 있는 디렉터리 내의 실행 파일을 수행시키려고 했을 때 발생함. 

403.2

 Forbidden, 금지 - 읽기 접근 금지. 이 에러는 브라우저가 접근한 디렉터리에 가용한 디폴트 페이지가 없을 경우에 발생함. 

403.4 

 Forbidden, 금지 - SSL 필요. 이 에러는 접근하려는 페이지가 SSL로 보안 유지되고 있는 것일 때 발생.

403.5 

 Forbidden, 금지 - SSL 128이 필요. 이 에러는 접근하려는 페이지가 SSL로 보안 유지되고 있는 것일 때 발생. 브라우저가 128비트의 SSL을 지원하는지를 확인해야 함. 

403.6 

 Forbidden, 금지 - IP 주소 거부됨. 이 에러는 서버가 사이트에 접근이 허용되지 않은 IP주소로 사용자가 접근하려 했을 때 발생함. 

403.7 

 Forbidden, 금지 - 클라이언트 확인 필요. 이 에러는 접근하려는 자원이 서버가 인식하기 위해서 브라우저에게 클라이언트 SSL을 요청하는 경우 발생함. 자원을 이용할 수 있는 사용자임을 입증하는데 사용됨. 

403.8 

 Forbidden, 금지 - 사이트 접근 거부. 이 에러는 웹 서버가 요청사항을 수행하고 있지 않거나, 해당 사이트에 접근하는 것을 허락하지 않았을 경우에 발생함. 

403.9 

 Forbidden, 금지 - 연결된 사용자수 과다. 이 에러는 웹 서버가 busy한 상태에 있어서 요청을 수행할 수 없을 경우에 발생함. 

403.10 

 Forbidden, 금지 - 설정이 확실하지 않음. 이 에러는 웹 서버의 설정 부분에 문제가 있을 경우 발생함. 

403.11 

 Forbidden, 금지 - 패스워드 변경. 이 에러는 사용자 인증 단계에서 잘못된 패스워드를 입력했을 경우 발생함. 

403.12 

 Forbidden, 금지 - Mapper 접근 금지. 이 에러는 클라이언트 인증용 맵(map)이 해당 웹 사이트에  접근하는 것을 거부할 경우에 발생. 

404 

 Not Found, 문서를 찾을 수 없음 - 이 에러는 클라이언트가 요청한 문서를 찾지 못한 경우에 발생함. URL을 다시 잘 보고 주소가 올바로 입력되었는지를 확인함. 

405 

 Method not allowed, 메소드 허용 안 됨 - 이 에러는 Request 라인에 명시된 메소드를 수행하기 위한 해당 자원의 이용이 허용되지 않았을 경우에 발생함.

406 

 Not Acceptable, 받아들일 수 없음 - 이 에러는 요청 사항에 필요한 자원은 요청 사항으로 전달된 Accept header에 따라 "Not Acceptable" 내용을 가진 사항이 있을 경우에 발생함. 

407 

 Proxy Authentication Required, Proxy 인증이 필요함 - 이 에러는 해당 요청이 수행되도록 proxy 서버에게 인증을 받아야 할 경우에 발생함.

408 

 Request timeout, 요청 시간이 지남 

409 

 Conflict 

410 

 Gone, 영구적으로 사용할 수 없음. 

411 

 Length Required 

412 

 Precondition Failed, 선결조건 실패 - 이 에러는 Request-header filed에 하나 이상에 선결 조건에 대한 값이 서버에서의 테스트 결과 false로 나왔을 경우에 발생 

413 

 Request entity too large 

414 

 Request-URI too long, 요청한 URI가 너무 김 - 이 에러는 요청한 URI의 길이가 너무 길어서 서버가 요청 사항의 이행을 거부했을 경우 발생

415 

 Unsupported media type 

500 

 Internal Server Error, 서버 내부 오류 - 이 에러는 웹 서버가 요청사항을 수행할 수 없을 경우에 발생함 

501 

 Not Implemented, 적용 안 됨 - 이 에러는 웹 서버가 요청사항을 수행하는데 필요한 기능을 지원하지 않는 경우에 발생 

502 

 Bad gateway, 게이트웨이 상태 나쁨 - 이 에러는 게이트웨이 상태가 나쁘거나 서버의 과부하 상태일 때 발생한다. 

503 

 Service Unavailable, 서비스 불가능 - 이 에러는 서비스가 현재 멈춘 상태 또는 현재 일시적인 과부하 또는 관리 상황일 때 발생될 수 있다. 

504 

 Gateway timeout 

505 

 HTTP Version Not Supported 



출처: http://hyeonstorage.tistory.com/97 [개발이 하고 싶어요]

반응형

+ Recent posts