조회 수 1595 추천 수 0 댓글 12
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부
Extra Form
라이선스 MIT

안녕하세요?


모처럼 선선한 주말 잘 보내고 계시는지요? ^^


예전에 SIR의 팁 게시판에 왕계란 님께서 작성하신 


Imgur를 이용해서 이미지를 첨부하는 방법(https://sir.kr/g5_tip/2790)을 참고하여


Dropbox를 이용하여 이미지를 첨부하는 보드스킨을 만들어보았습니다.



write.skin.php 파일은 그누보드와 아미나를 설치하면 기본적으로 선택되는 basic 보드를 기반으로 하여

(아미나 자료실에 한별아빠 님께서 올리신 Basic-board가 아니라 기본적으로 설치되어 있는 basic 보드입니다)


왕계란 님의 팁을 보면서 짜맞추는 방식으로 작성하였습니다.


왕계란 님께 이 글을 빌어서 감사드립니다!!


dropbox.php 파일은 구글링을 통해 아래 사이트들을 짜깁기해서 만들었습니다.


https://riptutorial.com/dropbox-api/example/1354/uploading-a-file-via-curl-in-php

https://riptutorial.com/dropbox-api/example/24125/creating-a-shared-link-for-a-file-using-curl-in-php


솔직히 완전 누더기 수준의 코딩이어서 이건 짜집퍼 수준도 아닌 정말 지저분한 코딩이 되었네요 ㅠㅠ



사용방법이 아주 직관적이지는 않아서 설명을 드리면요.


우선 아미나에서 구동 가능한 보드스킨에 write.skin.php 파일을 교체하고


/bbs 폴더에 dropbox.php 파일을 넣어주셔야 합니다.


그리고 관리자 설정에 들어가서 보드스킨을 변경하시고, DHTML을 허용하시면 됩니다.



설치를 완료하고 글 쓰기 버튼을 클릭하면 보드스킨 하단에 다음과 같이 Dropbox 버튼이 뜹니다.


Dropbox 로고가 청색 계통이어서 스킨의 다른 부분과 매치가 잘 되지는 않지만 청색 계통으로 버튼을 만들었네요 ^^




파일을 선택하여 전송 버튼을 누르면 Ajax를 이용하여 스킨 가장 아래부분에 업로드한 사진이 뜹니다.


캡쳐화면에서 보시듯이 여러 장의 사진도 한꺼번에 삽입할 수 있어요.


사진이 떴다는 것은 성공적으로 Dropbox의 '앱' 폴더에 업로드가 되었다는 의미에요 ^^


사진을 클릭하면 사진이 에디터 안에 들어갑니다.


주의할 점은 더블클릭하는 경우에는 사진이 연속으로 2장 들어갑니다 ㄷㄷ




작성완료 버튼을 눌러서 최종적으로 작성된 게시글을 조회한 화면입니다.


두 장의 사진 모두 성공적으로 삽입된 것을 확인할 수 있습니다.


참고로 이미지는 픽사베이에서 저작권 문제가 없는 파일로 골랐어요 ^^





/bbs 폴더에 넣어야 할 dropbox.php 파일입니다.


<?php
$API_KEY = 발급받은 API 키를 넣어주세요;

if(empty($API_KEY) || @$_FILES['up_load']['error'] !== 0) {
  exit;
}
$filetype = explode('/', mime_content_type($_FILES['up_load']['tmp_name']));
if($filetype[0] !== 'image') {
  die('이미지만 업로드를 허용합니다.');
}

$tmp = $_FILES['up_load']['tmp_name'];
$path_file = $_FILES['up_load']['name'];
move_uploaded_file($tmp, $path_file); // 업로드된 임시파일을 /bbs 폴더로 옮깁니다.
$timestamp = time(); // 파일명을 타임스탬프.확장자 형식으로 변경합니다.
$temp = explode('.', $path_file);
$extension = $temp[count($temp) - 1];
rename($path_file, $timestamp.'.'.$extension);
$path_file = $timestamp.'.'.$extension;
$fp = fopen($path_file, 'rb');
$size = filesize($path_file);

$cheaders = array('Authorization: Bearer '.$API_KEY,
                  'Content-Type: application/octet-stream',
                  'Dropbox-API-Arg: {"path":"/test/'.$path_file.'", "mode":"add"}');

$ch = curl_init('https://content.dropboxapi.com/2/files/upload'); // Dropbox에 이미지를 업로드합니다.
curl_setopt($ch, CURLOPT_HTTPHEADER, $cheaders);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, $size);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
fclose($fp);
@unlink($path_file); // /bbs 폴더에 위치한 이미지 파일을 삭제합니다.

$parameters = array('path' => "/test/".$path_file); // Dropbox에 업로드한 파일의 공유링크를 생성합니다.
$headers = array('Authorization: Bearer '.$API_KEY,
                 'Content-Type: application/json');
                 
$curlOptions = array(
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($parameters),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_VERBOSE => true
    );
$ch = curl_init('https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings');
curl_setopt_array($ch, $curlOptions);
$response = curl_exec($ch);
$json = json_decode($response, true); // 공유링크를 이미지 호스팅이 가능하도록 문자열 처리를 합니다.
$link_url = $json['url'];
$link_url = substr($link_url, 0, -1);
$link_url = $link_url.'1';
echo $link_url;
curl_close($ch);
?>



write.skin.php 파일은 중간중간 수정한 부분이 많고 너무 길어서 첨부파일로 올리겠습니다.

write.skin.php 



전반적으로 스크립트에 대해 간단히 설명을 드리자면


1. 파일을 /bbs 폴더에 업로드한 후 이를 Dropbox로 전송하여 공유링크를 얻고 이를 수정하는 과정을 거칩니다.


2. 파일명이 중복되면 업로드가 되지 않고 에러가 뜨는 문제가 있어서 파일명을 타임스탬프.확장자로 변경하였습니다.


3. Dropbox의 공유링크를 바로 이미지 호스팅 용도로 사용할 수 없어서 약간 수정해야 합니다.

(과거에는 바로 사용할 수 있는 기능이 있었으나, 현재는 막혀있습니다.)



이러한 방식의 장점은 다음과 같습니다.


1. 트래픽을 절약할 수 있습니다.

(트래픽 한도는 무료 회원은 20GB/day, 유료회원은 200GB/day입니다.)


2. imgur 플러그인을 이용하는 것과 비교하여 이미지 파일에 대한 관리가 용이합니다.

(현재도 그런지는 모르겠지만 imgur는 접속이 없으면 이미지가 삭제되는 경우도 있다고 알고 있습니다)


3. Dropbox 폴더 탐색기로 이미지 파일을 쉽게 확인할 수 있습니다.


4. Dropbox 유료회원의 경우 TB 단위로 용량을 마음껏 사용할 수 있습니다.



반면에 다음과 같은 단점이 있습니다.


1. 파일이 서버를 거쳐 Dropbox에 업로드되어 글 작성시에 트래픽이 2배로 소모됩니다.

(제 실력으로는 무리이지만 자바스크립트를 활용하여 브라우저에서 곧바로 Dropbox로 업로드하고

리턴받은 JSON 값을 서버로 전송하여 처리할 수 있다면 있다면 좋겠죠 ^^)


2. Dropbox 서버가 해외에 있어서 이미지 로딩속도가 빠르지 않습니다. 

(솔직히 imgur보다 살짝 느리거나 비슷한 수준인 것 같습니다)


3. Dropbox 알림을 켜놓으면 이미지 파일이 업로드될 때마다 윈도우에 알림이 뜹니다 ㅠㅠ

(사이트 관리의 측면에서는 오히려 유용할 수도 있겠네요?!)



솔직히 Dropbox 이미지 호스팅을 아미나 보드스킨으로 구현하는 것을 제 실력으로는 도저히 못할 것이라고 생각했는데요.


군더더기가 많고 지저분한 스크립트이지만 기능적인 측면만 놓고본다면 결과적으로 간신히 구현은 하였습니다 ㅠㅠ


평소에 여러모로 도움을 많이 주시는 마스터 님, humit 님, 네모 님, 라엘 님께 진심으로 감사드립니다!


기회가 되면 이미지 파일 이외에 일반 첨부파일도 Dropbox로 업로드할 수 있도록 만들어볼게요~



그럼 즐거운 주말 되시고 오늘 비가 온다던데 우산 챙기세요 ^^


장황한 글 읽어주셔서 감사합니다!


  • profile
    라엘 2019.07.17 00:43
    이런게 일취월장 이겠죠?! 역시!!
    1. 자바스크립트 업로드는 거의 절대로 구현하면 안됩니다. 스크립트 업로드의 90%의 예제는 보안취약점(소스코드에 비밀키가 공개됨)이 있으니 구현안하는게 좋습니다.
    2. 글쓰기 권한이 있는지 체크하는 코드가 있어야 할 것 같아요.
    그리고 파일명에 ip2long 같은 함수로 작성자IP와 회원아이디를 base64 해서 붙이는게 좋을것 같습니다. 저 상태로는 아무나 업로드 할 수 있기 때문에 보안문제가 발생할 수 있어요.
  • profile
    이니스프리 2019.07.17 20:36
    허걱 ㅠㅠ 일취월장과는 거리가 먼 짜집퍼 수준의 스크립트인데요~
    그렇게 말씀해주셔서 감사합니다!!
    기능적으로나 디자인적으로나 부족한 부분이 많은 스크립트라서 보완하도록 할게요 ^^

    1.
    말씀하신 자바스크립트 업로드라는 것이 자바스크립트를 이용하여 브라우저에서 Dropbox로 바로 업로드하는 것을 말씀하시는거죠?
    다음 예제를 활용하여 사용자의 PC -> 웹호스팅 -> Dropbox 순으로 순차적으로 업로드를 하는 것은 괜찮겠죠?
    http://jsfiddle.net/guest271314/0hm09yqo/
    웹호스팅의 PHP 파일을 거쳐 Dropbox로 전송이 되니 API key는 사용자에게 노출이 안 될 것이라고 생각되는데요.

    2.
    저는 단순히 아미나의 관리자 설정에서 레벨2(회원) 이상 글쓰기를 가능하게 하면 해결될줄 알았는데요.
    라엘 님께서 말씀하신 부분까지는 미처 생각하지를 못했네요 ㅠㅠ
    우선 if (!defined("_GNUBOARD_")) exit; 를 넣어서 외부에서 직접 파일에 접근하지 못하도록 해야할 것 같네요.
    그리고 말씀해주신대로 파일명에 IP와 ID를 넣는 것이 보안을 위해서나 나중에 파일 관리를 위해서나 좋을 것 같네요!

    여러모로 큰 도움을 주셔서 항상 감사드립니다 ^^
    주말에 태풍이 온다고 하던데 라엘 님께서도 태풍 조심하세요~
  • profile
    라엘 2019.07.18 17:00
    (제 실력으로는 무리이지만 자바스크립트를 활용하여 브라우저에서 곧바로 Dropbox로 업로드하고
    리턴받은 JSON 값을 서버로 전송하여 처리할 수 있다면 있다면 좋겠죠 ^^)
    라는거에 대한 의견이에요~
    javascript 로 직접 서버로 올리는건 최고관리자만 사용하는 페이지에만 적용하거나, 그 이외에는 시도해보지 않는게 좋아요.
    javascript 로 직접 업로드 예제 코드(dropbox, firebase, aws s3등등)를 보면 거의 다 취약하더라구요. 시크릿 키가 노출되는것을 막을 방법도 없고.

    오늘도 멋진 코드 짜주세요~
    감사합니다.
  • profile
    이니스프리 2019.07.18 18:39

    옙 바쁘신데 답변해주셔서 정말 감사합니다!!

    조언해주신대로 Javascript에서 직접 서버를 올리는 것은

    API key 노출 등 보안 취약점이 있으니 연습 용도로만 적용해봐야겠네요!

    (Dropbox API v2와 관련해서는 PHP에 대한 문서는 거의 없고, 오히려 Javascript와 관련된 문서가 많네요 ㄷㄷ)

    라엘 님 덕분에 또 한 수 배웠네요 ^^

    그럼 저녁식사 맛있게 드세요~ 항상 감사드립니다 :)

  • profile
    title: 황금 서버 (30일)humit 2019.07.19 17:29
    좋은 방법은 아니긴 하지만 시크릿 키를 노출하지 않고 클라이언트 쪽에서 동작하게 하려면

    엑세스 토큰을 발급하고, 30초 혹은 60초 후에 해당 토큰을 revoke하도록 예약을 한 다음 해당 엑세스 토큰을 응답으로 주는 API를 만들어서
    해당 API를 호출해서 얻은 토큰으로 업로드를 하도록 API를 호출하는 방법이 있긴 하겠습니다 ㅋㅋㅋㅋㅋ

    다만 이렇게 클라이언트 쪽에서 업로드를 하게 하면 업로드를 하는 파일을 제한하는 것이 불가능하기 때문에 안쓰는게 좋겠지요 ㅎㅎ
  • ?
    포인트 폭탄+ 2019.07.19 17:29
    humit님 축하합니다.
    추가로 200포인트만큼 포인트 폭탄+를 받았습니다.
  • profile
    이니스프리 2019.07.20 00:13
    앗 감사합니다! 그런 방법이 있긴 하군요 ㅎㄷㄷ
    아직 제가 Javascript를 잘 다루지 못하지만 일단 말씀해주신 방법도 공부는 해볼게요~

    일단 지금 만들어놓은 것에 jquery로 drag and drop 업로드와 progress bar 정도 추가해보려고 하는데요.
    그런데 업로드가 브라우저 -> 웹호스팅 서버 -> Dropbox의 두 단계로 이루어지다보니
    브라우저에서 웹호스팅 서버까지는 progress bar를 구현할 수 있겠는데
    이걸 다시 Dropbox로 업로드하는 것은 구글링해도 예제가 없더군요 ㅠㅠ
    이론적으로 progress bar를 구현하기 어려울까요??

    그럼 태풍이 온다는데 humit 님께서도 태풍 조심하시고 즐거운 주말 되세요!
    항상 감사드립니다 ^-^
  • profile
    title: 황금 서버 (30일)humit 2019.07.20 00:26
    조금 옛날 글이긴 하지만 Dropbox API로 업로드를 할 때 progress를 알려주지는 않는다고 하네요..
    https://www.dropboxforum.com/t5/API-Support-Feedback/How-To-Get-Upload-Progress-Of-A-Uploading-File-With-Dropbox-Core/td-p/109135

    다만 저기에도 나와있다시피 chuckUpload 메서드를 사용하면 구현이 가능합니다. 파일을 일정 단위만큼 잘라서 (ex 1MB 등) 요청을 보내고 해당 응답이 오면 클라이언트에게 알려주고 클라이언트가 다음 블록을 업로드해야 한다고 알려주면 서버에서 다음 블록을 업로드 하는 식으로 해서 이 과정을 남은 블록이 없을 때까지 해당 과정을 반복하면 됩니다.

    파일을 자르는 단위는 서버와 Dropbox 간의 응답 속도를 보고 조정을 하시면 됩니다. 너무 작으면 자주 응답을 주고받기 때문에 오버헤드가 크고, 너무 크면 progress bar 업데이트가 늦어지기 때문에 실험을 해보시는게 좋습니다.
  • profile
    이니스프리 2019.07.20 00:56

    앗 밤늦게 답변 달아주셔서 정말 감사합니다!!

    chuckUpload를 이용하는 방법으로 가능하긴 하군요 ㅎㄷㄷ

    Dropbox API가 v2로 넘어가기는 했는데 아직 deprecated 되지 않았으면 좋겠네요~

    사실 브라우저에서 웹호스팅 서버로 넘어가는 단계의 progress bar도 예제를 보면서베끼면서 간신히 구현한 것이라서요 ㅠㅠ

    일단 말씀해주신 방법으로 시도해보겠습니다!!

    두 단계의 progress bar를 한꺼번에 또는 순차적으로 보여주면서 디자인 측면에서도 무난하게 구현하기가 쉽지 않겠네요.

    그럼 굿밤 되시고 즐거운 주말 되세요 ^-^

  • profile
    title: 황금 서버 (30일)humit 2019.07.20 01:10
    v2면 upload_session/start, upload_session/append, upload_session/finish 쪽을 활용하시면 될 것 같습니다 :)
  • profile
    이니스프리 2019.07.20 01:51
    허거걱 ㅠㅠ 정말 감사합니다!!
    제가 REST API를 별로 안 다뤄봐서 이 방면으로 검색능력이 떨어지는데
    말씀하신 내용을 참고해서 열심히 만들어보겠습니다 ^-^
    그럼 humit 님께서도 안녕히 주무세요~
    감사합니다!
  • ?
    감자칩 2022.01.09 21:07
    안녕하세요 이 게시글써보려 가입했는데요. 아미나에 넣어보니까 동작하지않아서요. 지금은 쓸 수 없는 자료인가요?

  1. AWSCLI, in a single file (portable, linux)

  2. [Python-Gnuboard] 파이썬으로 구현한 그누보드 자동 글쓰기 함수

  3. [Python] 휴일지킴이 약국을 크롤링하여 Folium 지도에 마커로 표시하는 PyQt 윈도우 앱

  4. 도박 중독자를 위한 광고 차단 규칙

  5. [Python] 유튜브 영상을 다운받아 일정 간격으로 캡쳐하여 10장씩 merge하기

  6. [Autohotkey] 매분 정각에 전체화면을 캡쳐하는 스크립트

  7. [Python/Telegram] Studyforus 알림봇 (댓글, 스티커 파싱)

  8. [Python] url 주소로부터 IP 주소 알아내기

  9. [Python] 네이버 실시간 검색어

  10. Koa에서 자동으로 라우팅 채워주기

  11. JavaScript에서 파이썬 문자열 처리 함수 중 하나 (바인딩)를 구현

  12. [Python] Google Image Search 결과를 받아오기

  13. [파이썬] Requests를 사용한 네이버 카페 크롤링 - 일정수 이상의 리플이 달린 게시글만 텔레그램 알림

  14. [JS] 클라이언트단 GET Parameter

  15. [Python] 싸이월드 미니홈피 백업 스크립트

  16. [Python] PIL을 이용한 Animated GIF의 리사이징

  17. [PyQt] sir.kr에서 스크랩한 게시글을 보여주는 윈도우앱 (검색 및 정렬 가능)

  18. [아미나] Dropbox API를 이용한 이미지 호스팅 보드스킨

  19. [Python] 네이버 모바일 이미지 검색에서의 이미지 파일을 멀티스레드로 다운받고 1개의 파일로 병합

  20. [PHP/Javascript] 아미나에 자동으로 게시글을 생성하고 Ajax로 전송하여 결과를 표시하기

Board Pagination Prev 1 2 3 4 Next
/ 4