컴퓨터/Linux

Geoserver + Openlayers CORS 문제 해결 방법

dolhim 2017. 2. 9. 19:40


Linux에 Geoserver를 설치한 다음, OpenLayers로 WMS Tile을 생성했다.

그런데, 레이어를 도시할 때마다, CORS 에러가 난다.


이는, 브라우저를 실행할 때

명령창에서 '--disable-web-security' 옵션을 추가하고 크롬을 실행하면 일시적으로 해결된다.


하지만, 실제 운영되는 환경으로 세팅해야 했기 때문에 근본적으로 해결할 수 있는 방법을 찾기로 했다.



먼저, CORS(Cross-Origin Resource Sharing)란 무엇인가?


모질라 홈페이지에서는 아래와 같이 나와있다.


처음 서브되는 리소스의 도메인과 다른 도메인으로부터 리소스가 요청될 경우 해당 리소스는 cross-origin HTTP 요청에 의해 요청됩니다. 예를 들어, http://domain-a.com으로부터 서브되는 HTML 페이지가 <img> src 속성을 통해 http://domain-b.com/image.jpg를 요청하는 경우가 있습니다. 오늘날 많은 웹 페이지들은 CSS 스타일시트, 이미지, 그리고 스크립트와 같은 리소스들을 각각의 출처로부터 읽어옵니다.

보안 상의 이유로, 브라우저들은 스크립트 내에서 초기화되는 cross-origin HTTP 요청을 제한합니다.

...

웹 애플리케이션은 자신과 동일한 도메인으로 HTTP 요청을 보내는 것만 가능했습니다. ...

출처 : Mozilla 재단 - HTTP 접근 제어 (CORS)


요약하면, 다른 도메인을 통해 XMLHttpRequest API 혹은 (캔버스에 드로잉 되는 픽셀 처리나 WebGL 등의) 리소스를 호출 할 경우, 보안상의 이유로 제한한다는 것이다.


(이번 케이스에서는 Openlayers로 WMS레이어를 호출 할 때, GET 혹은 POST 요청을 보내거나, 

WebGL 혹은 래스터를 드로잉하는데 어느 쪽에 해당되는 아직 잘 모르겠다.)



구글링 결과 해결 방법은 대략 두가지로 나뉜다.


1. Proxy를 사용한다.

2. 서버 설정에서 CORS(Cross-Origin Resource Sharing)를 허용하고, 코드 상에 "crossOrigin: 'anonymous'" 속성을 추가한다.



이 중에서 2번 방법으로 해결하였다.



1. 서버 설정 (Jetty)


- 실행 환경

    OS : Linux CentOS 6.8 x64

    Server : Geoserver 2.10.1 (Jetty 9.2.13.v20150730) 

        -> Geoserver 압축 파일을 해제하는 형태로 설치했다. (stand-alone)

            만약, 톰캣 위에 WAR로 설치했다면, 아래에 나오는 xml 코드가 달라지므로 유의해야한다..


- 방법

Java 설치 등 서버 실행 환경이 제대로 설정되어있다고 가정한다.



1. 먼저, jetty-servlet-9.2.13.v20150730.jar 파일을 다운로드한다. 


2. 위 파일을 [GEOSERVER_HOME]/webapps/geoserver/WEB-INF/lib/에 복사한다.

참고로, [GEOSERVER_HOME]/lib/jetty-servlets-9.2.13.v20150730.jar 파일과는 전혀 다른 파일이다..

s가 빠져있다. 그리고, 위치도 다르다. 영못알(은 나)이 구글링하며 겪게되는 뻘짓의 원인



3. WEB-INF/web.xml 파일에 아래 코드를 추가한다. 
해당 URL 패턴에 대하여 Cross Origin 기능을 필터링 하겠다는 의미이다.


1
2
3
4
5
6
7
8
<filter>
   <filter-name>cross-origin</filter-name>
   <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>cross-origin</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
cs



참고 : W3C -  CORS Enabled - For Jetty (7 and above) 

        -> Jetty CORS 허용 설정 방법 


참고 : OSGeo JIRA - Geoserver - [GEOS-6605] Enable CORS Support 

        -> OSGeo 공식 이슈트래커에 java.lang.ClassNotFoundException:org.eclipse.jetty.servlets.CrossOriginFilter 에러에 대한 해결 방법이 서술되어있음




2. OpenLayers3 코드


WMS 타일을 생성할 때, 아래와 같이 'crossOrigin' 속성에 'anonymous'값을 추가한다.


1
2
3
4
5
6
7
8
9
10
var wmsSource = new ol.source.TileWMS({
  url: 'https://ahocevar.com/geoserver/wms',
  params: {'LAYERS''ne:ne'},
  serverType: 'geoserver',
  crossOrigin: 'anonymous'
});
 
var wmsLayer = new ol.layer.Tile({
  source: wmsSource
});
cs



참고 : Openlayers Example - WMS GetFeatureInfo (Tile Layer) -> Openlayers 공식 홈페이지 WMS 레이어 생성 예제 



잘된당.


문제시 수정