본문으로 건너뛰기

HTTP Storage

HTTP Storage는 S3나 WebDAV 인터페이스를 제공하지 않는 저장소를 Office에 연결하기 위한 어댑터입니다. 고객은 기존 서비스에 HTTP Storage Protocol을 구현하거나, 저장소 API를 호출하는 별도 HTTP Storage Provider를 만들 수 있습니다. Office는 Provider에 서명된 요청을 보내 문서를 읽고 저장합니다.

HTTP Storage 구성 요소와 데이터 흐름Office 내장 HTTP Storage Adapter가 서명된 요청을 고객 Provider로 보냅니다. Provider는 요청과 고객의 문서 권한을 확인한 뒤 문서를 읽거나 저장합니다.구성 요소와 데이터 이동Thinkfree Office (TFO)고객 서비스문서 편집기 · Office 런타임HTTP Storage AdapterOffice에 내장info / get / put세션 · 문서 권한문서 저장소HTTP Storage Provider고객이 구현·운영권한 확인허용 후읽기·쓰기서명된 HTTP 요청JWT + bodyJSON 또는 문서 바이트같은 공유 키로 요청을 서명·검증하고, HTTPS로 전송 내용을 보호합니다.

예제 Provider 실행해 보기​

직접 Provider를 구현하기 전에 Thinkfree가 제공하는 예제 서버를 실행해 Office와 연결해 볼 수 있습니다. 샘플 문서의 목록을 조회하고, 문서를 열어 편집·저장하는 흐름을 확인하는 단계입니다.

공개 예제 저장소는 Node.js, Spring Boot, FastAPI로 구현한 전체 서버와 샘플 문서를 제공합니다. 각 예제는 Provider의 로컬 디렉터리를 저장소로 사용하며, 모든 프로토콜 작업을 기본으로 지원합니다.

이 가이드의 어댑터 이름은 http-remote-directory입니다. 문서 폴더는 Provider 서버에 있으며, Office는 HTTP로 접근합니다. Office 서버의 폴더를 직접 읽는 Host Storage와 구분해 이름을 정한 예시입니다.

아래에서는 Node.js 예제를 실행합니다. Node.js를 설치한 뒤 다음 명령으로 예제 코드를 내려받고 서버를 시작합니다. Office가 사용하는 포트 8080과 겹치지 않도록 예제 Provider는 9090에서 실행합니다.

git clone https://github.com/thinkfree/http-storage-provider.git
cd http-storage-provider
npm install
npm run init
TFO_STORAGE_HOST=0.0.0.0 TFO_STORAGE_PORT=9090 npm start

npm run init은 로컬 설정을 만들고 어댑터 이름 http-remote-directory와 생성한 요청 서명 시크릿을 표시합니다. 이 두 값을 관리자 페이지에서 사용합니다. 시크릿은 Office와 Provider에 같은 값을 설정하며, 소스나 로그에 남기지 않습니다.

이미 설정 파일이 있으면 npm run init은 기존 이름과 시크릿을 유지합니다. 이 경우 기존 설정의 어댑터 이름을 아래 예제에도 사용합니다.

위 명령은 다른 컨테이너의 Office가 연결할 수 있도록 네트워크 인터페이스에 바인딩합니다. Provider base URL에는 Office에서 접근할 수 있는 서버 IP 또는 DNS 이름과 포트 9090을 사용합니다. Office 컨테이너 안의 127.0.0.1은 그 컨테이너 자체를 가리키므로 호스트에서 실행한 Provider 주소로 사용할 수 없습니다. 신뢰할 수 있는 네트워크 밖에서는 HTTPS로 제공합니다.

별도 터미널에서 같은 디렉터리의 다음 명령을 실행합니다.

TFO_STORAGE_PORT=9090 npm run smoke

Signed listing succeeded와 샘플 파일명이 표시되면 Provider가 서명된 목록 요청에 정상 응답한 것입니다.

다른 프로그래밍 언어의 Provider 예제​

Git 저장소에는 Node.js 예제 외에도 Java의 Spring Boot와 Python의 FastAPI로 구현한 Provider 예제가 있습니다. 사용할 프로그래밍 언어에 맞는 예제를 선택하고 각 가이드에서 실행·설정 방법을 확인합니다.

구현실행 위치와 명령실행 가이드 · 프로토콜 검증 테스트
Node.js저장소 루트에서 위 명령 실행가이드 · test/app.test.mjs, npm test
Spring Bootexamples/java에서 ./run.sh가이드 · HttpStorageProviderApplicationTest.java, mvn test
FastAPIexamples/python에서 ./run.sh가이드 · test_app.py, .venv/bin/python -m unittest -v

Spring Boot는 Java·Maven·OpenSSL, FastAPI는 Python과 venv·pip가 필요합니다. 두 예제의 기본 포트는 8080입니다. 첫 실행이 만든 설정 파일에서 포트와 바인딩 주소를 바꾼 뒤 다시 실행합니다. Java는 .env.java의 TFO_STORAGE_PORT·TFO_STORAGE_HOST, Python은 .provider-config.json의 port·host를 사용합니다.

Office에 HTTP Storage 어댑터 등록하기​

  1. Office 관리자 페이지에 로그인합니다.

  2. 외부연동(External linkage)에서 어댑터 추가(Add Adapter)를 누르고 유형으로 HTTP Storage를 선택합니다.

  3. 다음 값을 입력합니다. 아래 예시는 Provider 서버의 주소를 storage.example.com, 포트를 9090으로 사용합니다. storage.example.com은 예시 도메인이므로 Office에서 접근할 수 있는 실제 서버 IP나 도메인으로 바꿉니다.

    항목입력값
    이름(Name)Provider에 설정한 어댑터 이름. Node.js 예제는 http-remote-directory
    Provider Base URL(Provider base URL)http://storage.example.com:9090. /tfo-http-storage/v1과 문서 경로는 붙이지 않음
    요청 서명 시크릿(Request signing secret)npm run init이 생성한 값. Provider에 설정된 시크릿과 같은 값을 입력
  4. 연결 테스트(Test connection)를 실행합니다. 아래와 같이 연결과 파일 목록 조회가 성공했다는 메시지가 표시되면 등록(Register)을 누릅니다. 어댑터 목록에 http-remote-directory가 실행 중(Running)으로 표시되는지 확인합니다.

다음은 Node.js 예제의 값을 입력하고 연결 테스트를 완료한 화면입니다. 요청 서명 시크릿은 가려져 있습니다.

Node.js 예제의 http-remote-directory와 Provider 주소를 입력하고 연결 테스트에 성공한 영어 HTTP Storage 등록 화면

등록한 어댑터의 파일 찾아보기(Browse files)를 열면 Provider의 문서 목록을 확인할 수 있습니다. Node.js 예제의 samples 폴더에는 sample.docx, sample.xlsx, sample.pptx가 있습니다.

연결 테스트는 Provider 루트의 list를 호출합니다. Provider가 목록 기능을 구현하지 않았다면 정확한 LIST_NOT_SUPPORTED 응답을 받은 경우에만 파일 탐색을 사용할 수 없다는 안내를 확인하고 등록할 수 있습니다. 인증 실패나 다른 연결 오류는 먼저 해결합니다.

요청 서명 시크릿

요청 서명 시크릿은 Office가 요청에 서명하고 Provider가 이를 검증할 때 사용하는 공유 비밀값입니다. Office와 Provider에 같은 값을 설정해야 합니다. Provider는 서명과 실제 요청 내용을 검증해 요청의 위·변조 여부를 확인합니다.

어댑터 이름과 요청 서명 시크릿은 등록 후 변경할 수 없습니다. 다른 값으로 연결하려면 Provider 설정과 값을 맞춰 새 어댑터를 등록합니다.

문서 URL 만들기​

Office URL에는 등록한 어댑터 이름과 Provider의 저장소 루트를 기준으로 한 상대 경로를 넣습니다. Node.js 예제의 storage/samples/sample.docx를 열려면 다음 주소를 사용합니다. Office의 주소나 포트를 바꿨다면 http://localhost:8080을 해당 주소로 바꿉니다.

항목값
Office 주소http://localhost:8080
Name(이름)http-remote-directory
Provider의 저장소 루트예제 저장소의 storage/
Provider에 있는 파일storage/samples/sample.docx
URL에 넣을 문서 경로samples/sample.docx

Office 주소 뒤에 /cloud-office/api/, 어댑터 이름, 저장소 루트 아래 상대 경로와 /open을 붙입니다.

http://localhost:8080/cloud-office/api/http-remote-directory/samples/sample.docx/open?app=WORD_EDITOR&user_id=test-user&docId=httpsample001

storage/는 Provider의 로컬 루트이므로 URL에 넣지 않습니다. 관리자 화면에 입력한 Provider base URL도 Office URL에 포함하지 않습니다. Provider 주소는 Office가 아래 프로토콜 요청을 보낼 때 사용합니다. 경로에 공백이나 한글이 있으면 각 경로 세그먼트를 URL 인코딩합니다. user_id는 사용자 식별자, docId는 Office에서 문서를 구분하는 고유한 ID로 지정합니다. 파일 종류별 app과 전체 옵션은 문서 URL 생성을 참고합니다.

Office가 문서를 열 때 Provider에 보내는 요청은 별도의 프로토콜 URL을 사용합니다.

Provider base URL: http://storage.example.com:9090
Document path: samples/sample.docx

GET http://storage.example.com:9090/tfo-http-storage/v1/samples/sample.docx/info
GET http://storage.example.com:9090/tfo-http-storage/v1/samples/sample.docx/get

고객 세션 정보 전달하기​

__tfo_adapter_http_storage_client_metadata는 고객 애플리케이션의 정보를 Office를 거쳐 Provider에 전달하는 선택적 문서 열기 매개변수입니다. 어댑터 등록 화면의 설정값이나 Provider 주소에 붙이는 매개변수가 아닙니다. 문서를 여는 요청에 JSON 문자열로 넣으면 HTTP Storage Adapter가 이를 객체로 읽고, Provider에 보내는 요청 JWT의 request.client_metadata에 포함합니다.

Provider에서 고객 문서 세션을 요구한다면, 고객 애플리케이션이 사용할 문서와 유효 기간을 정한 고객 세션 토큰을 발급하고 문서를 열 때 전달해야 합니다. 아래 userSessionToken는 예시이며, 의미와 현재 권한 확인 방법은 고객 서비스에서 정합니다.

const openUrl = new URL(
'/cloud-office/api/http-remote-directory/samples/sample.docx/open',
'http://localhost:8080',
);
openUrl.searchParams.set('app', 'WORD_EDITOR');
openUrl.searchParams.set('user_id', 'test-user');
openUrl.searchParams.set('docId', 'httpsample001');
openUrl.searchParams.set('__tfo_adapter_http_storage_client_metadata', JSON.stringify({
userSessionToken: 'replace-with-a-short-lived-document-session',
}));

URLSearchParams가 URL 인코딩을 처리하므로 JSON을 따로 인코딩하지 않습니다. Provider는 JWT 서명을 검증하고 JWT에 담긴 요청 정보를 실제 HTTP 요청과 비교해, 전송 중 내용이 바뀌지 않았는지 확인합니다. 고객 세션의 유효성과 문서 접근 권한은 별도로 확인해야 합니다. 위 예시 값을 입력한다고 유효한 세션이 만들어지는 것은 아닙니다.

서명된 문서 열기 티켓을 사용하는 경우에는 command.params 안의 같은 이름에 JSON 문자열을 넣습니다. 쿼리 매개변수로 서명된 값을 덮어쓸 수 없습니다. 입력 JSON은 UTF-8 기준 최대 4,096바이트이며, 메타데이터를 포함한 전체 요청 JWT는 8,192바이트를 넘을 수 없습니다.

Provider는 요청마다 JWT와 실제 HTTP 요청을 검증한 뒤 request.client_metadata.userSessionToken를 읽고 고객 서비스의 세션 저장소에서 사용자, 대상 문서, 만료와 허용 작업을 확인합니다. 값이 누락되거나 만료·폐기됐으면 해당 고객 세션이 필요한 작업을 거부해야 합니다. 공개 예제는 요청 서명 검증을 제공하며, 이 고객 세션 확인은 사용할 서비스에 맞게 직접 구현합니다.

고객 세션 메타데이터 전달과 작업별 권한 확인 시퀀스Office 내장 HTTP Storage Adapter가 서명된 요청을 고객 Provider로 보냅니다. Provider는 요청과 고객의 문서 권한을 확인한 뒤 문서를 읽거나 저장합니다.고객 세션 전달과 요청별 권한 확인고객 애플리케이션TFO · HTTP Storage AdapterHTTP Storage Provider사용자·문서 권한 확인짧은 유효 기간의 세션 발급1. /open + metadata JSON2. info + JWT (client_metadata)JWT·실제 요청 검증세션 저장소에서 읽기 권한 확인3. 파일 정보 또는 접근 거부4. get / put + fresh JWT요청마다 다시 확인세션·대상 문서·읽기/쓰기 권한같은 메타데이터를 전달해도 만료·폐기된 세션이나 허용되지 않은 작업은 거부합니다.

메타데이터는 암호화되지 않으며, 쿼리로 전달하면 URL에 포함됩니다. 로그인 쿠키나 장기 자격 증명을 넣지 않습니다. 전체 입력 조건과 접근 권한 확인 기준은 고객 메타데이터를 참고합니다.

Provider 직접 구현해 보기​

Provider를 구현하려면 Office에서 문서를 열고 편집·저장한 뒤 닫을 때 아래 작업이 어떤 역할을 하는지 알아야 합니다. 문서를 열 때는 info로 정보를 조회하고 get으로 내용을 내려받으며, 편집 결과를 저장소에 반영할 때는 put을 사용합니다. lock과 unlock을 지원한다면 편집 중인 문서에 lock을 설정하고 해제합니다.

Office는 편집기로 이동하기 전에 Provider의 info를 호출해 문서 정보를 확인합니다. Provider는 요청과 문서 읽기 권한을 검증하고, 접근이 거부되면 오류를 반환해야 합니다. 이후 요청의 순서와 횟수는 편집기 상태에 따라 달라질 수 있습니다.

문서 열기와 이후 조회·저장 시퀀스Office 내장 HTTP Storage Adapter가 서명된 요청을 고객 Provider로 보냅니다. Provider는 요청과 고객의 문서 권한을 확인한 뒤 문서를 읽거나 저장합니다.문서 열기와 후속 저장소 요청TFOHTTP Storage AdapterHTTP Storage Providerinfo()GET …/info + request JWTJWT·실제 요청 검증세션·문서 읽기 권한 확인파일 정보 또는 접근 거부확인 결과info 성공 + readable 확인 후에만 편집기로 이동 · 거부되면 열기 중단내용 읽기 get() / 변경 저장 put()GET …/get / PUT …/put + fresh JWT문서 바이트 / 저장된 docIdProvider는 모든 요청에서 JWT와 문서 접근 권한을 확인합니다.

예제를 기반으로 구현할 때는 파일시스템을 읽고 쓰는 부분을 사용할 저장소의 API로 바꿉니다. 요청 인증과 경로 검증은 유지합니다. 전체 Request·Response 규격은 HTTP Storage Protocol에서 확인합니다.

작업역할구현 범위
info, get문서 정보 조회와 다운로드문서를 열기 위해 필수
put편집한 전체 문서 저장저장을 제공할 때 구현
list디렉터리의 바로 아래 항목 조회파일 탐색을 제공할 때 구현
lock, unlock문서의 lock 설정과 해제둘 다 구현하거나 둘 다 미지원으로 선언
mkdir, rename, delete디렉터리 생성, 이름 변경, 삭제제공할 기능만 구현

처리 순서는 다음과 같습니다.

  1. 요청 메서드·경로·본문 형식과 크기를 검사하고, 수신한 본문의 길이와 SHA-256을 계산합니다.
  2. JWT 서명과 유효 기간을 검증합니다. JWT의 어댑터 이름은 Provider 설정과 비교하고, 메서드·경로·본문 길이·SHA-256은 실제 요청과 비교합니다. 이미 사용한 요청 ID도 거부합니다.
  3. 인증된 요청의 문서 접근 권한을 확인한 뒤 저장소 작업을 수행합니다. 선택적 작업을 지원하지 않으면 해당 작업의 정확한 501 응답을 반환합니다.
  4. info·list·get·put 응답은 실제 바이트 길이를 Content-Length로 보냅니다. 저장할 때는 요청 검증과 권한 확인을 마친 뒤 문서를 저장하고, 저장된 문서의 docId 하나만 포함하는 JSON 객체를 반환합니다. 검증이나 저장에 실패했을 때 기존 문서가 손상되지 않도록 처리합니다. 형식과 ID 유지 규칙은 PUT 응답을 참고합니다.

info·list·put의 응답 JSON은 각각 최대 5 MiB, 문서는 300 MiB입니다. 이 JSON 응답과 get 응답은 chunked 전송이나 압축을 사용하지 않습니다. 서명 검증, 응답 형식과 크기 제한, 기능 미지원 응답에 정확한 규칙이 있습니다.

put을 지원하지 않으면 저장은 실패합니다. lock·unlock을 지원하지 않는 경우 Office는 각 작업의 규격에 맞는 미지원 응답을 성공으로 처리하지만 문서에 lock을 설정하지는 않습니다. 동시 편집 시 마지막 저장으로 덮어쓸지, 충돌을 거부할지 저장소 정책을 정하고 확인합니다.

연결 확인하기​

  • 예제의 프로토콜 검증 테스트를 실행해 잘못된 서명, 재사용된 JWT, 잘못된 경로와 크기 초과 요청을 거부하는지 확인합니다.
  • 샘플 문서를 열고 편집·저장·다시 열기까지 확인합니다. 구현한 list·lock·unlock·mkdir·rename·delete도 테스트용 문서로 확인합니다.
  • 고객 세션을 사용한다면 값 누락·만료·폐기·다른 문서의 세션을 거부하고, 읽기 전용 세션으로 저장할 수 없으며, 권한 확인 서비스 장애 시에도 저장소 접근을 허용하지 않는지 확인합니다.
  • 선택적 작업을 생략했다면 인증 후 정확한 미지원 응답을 반환하는지, 실제 저장소 오류와 구분되는지 확인합니다.

세부 오류 코드는 프로토콜 오류 응답, 운영 환경의 접근 제어·재전송 방지·파일 처리 기준은 Provider 운영 가이드를 참고합니다.