채택완료

게시판 첨부파일 다운 받을려면 비밀번호 입력하도록

게시판 첨부파일 다운 받을려면 비밀번호 입력하도록 하는 방법은 없을까요?
권한을 설정하거나, 유효기간을 적용하는 것은 있는데.

비회원도 볼 수 있는 게시판에서 첨부파일을 다운로드 받을 시~ 사전에 설정한 비밀번호를 입력해야만 다운로드 받을 수 있게 하는 것은 없을까요??

포인트 차감 개념이 아닌. 비밀번호.. 
글등록 할때 첨부파일에 대한 비밀번호를 설정해서..




- 게시판별 첨부파일 다운로드 권한 설정
https://sir.kr/boards/g5_tip/24168?search_type=subject_content&keyword=%EC%B2%A8%EB%B6%80%ED%8C%8C%EC%9D%BC

- 첨부파일 다운로드 유효기간 적용하기
https://sir.kr/boards/g5_tip/23643?search_type=subject_content&keyword=%EC%B2%A8%EB%B6%80%ED%8C%8C%EC%9D%BC
|

답변 2개

채택된 답변
+20 포인트
gnuboard5-v5.6.23 원본 basic 스킨 을 기준으로 설명 드리겠습니다
  1. 글 작성 시 wr_10 여분필드에 비밀번호 입력
  2. 첨부파일 클릭 → 비밀번호 모달 팝업
  3. 입력값을 download_pw_check.php로 AJAX 검증
  4. 일치 시 세션 저장 후 다운로드 진행

1

원본 write_skin.php 줄 번호를 기준으로 추가할 위치와 소스
원본에서 이 부분을 찾으세요
Copy
// 원본 약 118~121번째 줄 (파일 루프 종료 직후)
    <?php } ?>            ← 파일첨부 for 루프 마지막 닫는 태그
    <?php if ($is_use_captcha) { //자동등록방지  ?>

이 두 블록 사이에 아래 코드를 삽입하세요.
Copy
<?php } ?> ← 기존 파일루프 닫는 태그 (그대로 유지)


    <?php if ($is_file) { // 파일첨부가 활성화된 게시판에서만 표시 ?>
    <div class="bo_w_file_pw write_div">
        <label for="wr_10"><i class="fa fa-lock" aria-hidden="true"></i> 첨부파일 비밀번호</label>
        <input type="text"
               name="wr_10"
               id="wr_10"
               value="<?php echo ($w == 'u') ? htmlspecialchars($write['wr10']) : ''; ?>"
               class="frm_input half_input"
               size="30"
               maxlength="50"
               placeholder="첨부파일 비밀번호 (미입력 시 비밀번호 없음)"
               autocomplete="off">
        <p class="bo_w_file_pw_desc" style="font-size:12px; color:#888; margin:4px 0 0 0;">
            <i class="fa fa-info-circle" aria-hidden="true"></i>
            비밀번호를 설정하면 첨부파일 다운로드 시 비밀번호를 입력해야 합니다.
        </p>
    </div>
    <?php } ?>

    <?php if ($is_use_captcha) { //자동등록방지  ?>   ← 기존 캡챠 줄 (그대로 유지)
2
① 원본 view_skin.php 기준으로 3곳을 수정합니다
파일 최상단 — PHP 변수 선언 추가
원본 3~5번째 줄
Copy
// 원본
if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
include_once(G5_LIB_PATH.'/thumbnail.lib.php');

// add_stylesheet ...
add_stylesheet('<link rel="stylesheet" href="'.$board_skin_url.'/style.css">', 0);
?>
수정 후 — add_stylesheet 바로 아래, ?> 닫기 전에 삽입
Copy
if (!defined("_GNUBOARD_")) exit;
include_once(G5_LIB_PATH.'/thumbnail.lib.php');

add_stylesheet('<link rel="stylesheet" href="'.$board_skin_url.'/style.css">', 0);

// ▼ 추가 시작 ▼
// wr_10에 비밀번호가 설정되어 있는지 확인
$has_file_password = !empty(trim($view['wr10']));

// 세션에 이미 인증됐는지 확인
if (!isset($_SESSION)) @session_start();
$dl_already_authed = isset($_SESSION['dl_pw_ok'][$bo_table][$view['wr_id']])
                     && $_SESSION['dl_pw_ok'][$bo_table][$view['wr_id']];

// 비밀번호 검증 스크립트 URL (스킨 폴더 내 download_pw_check.php)
$dl_pw_check_url = $board_skin_url . '/download_pw_check.php';
// ▲ 추가 끝 ▲
?>
② <script src="viewimageresize.js"> 바로 다음 — 모달 HTML/CSS/JS 삽입 원본 8번째 줄 부근
Copy
// 원본
?>

<script src="<?php echo G5_JS_URL; ?>/viewimageresize.js"></script>

<!-- 게시물 읽기 시작 { -->
수정 후 — viewimageresize.js 스크립트 태그와 <!-- 게시물 읽기 시작 --> 사이에 삽입
Copy
<script src="<?php echo G5_JS_URL; ?>/viewimageresize.js"></script>

<?php if ($has_file_password && !$dl_already_authed && !$is_admin): ?>
<!-- ===== 첨부파일 비밀번호 모달 CSS ===== -->
<style>
#dlpw_overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.55);
    z-index: 9998;
    align-items: center;
    justify-content: center;
}
#dlpw_overlay.active { display: flex; }
#dlpw_modal {
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 8px 32px rgba(0,0,0,.22);
    padding: 32px 28px 24px;
    width: 100%;
    max-width: 360px;
    position: relative;
    z-index: 9999;
    text-align: center;
}
#dlpw_modal h3 { margin: 0 0 6px; font-size: 17px; color: #222; }
#dlpw_modal p  { margin: 0 0 18px; font-size: 13px; color: #777; }
#dlpw_input {
    width: 100%; box-sizing: border-box;
    padding: 10px 12px; border: 1px solid #ccc;
    border-radius: 5px; font-size: 15px;
    letter-spacing: 2px; margin-bottom: 10px;
    outline: none; transition: border .2s;
}
#dlpw_input:focus { border-color: #3c7fe0; }
#dlpw_error { display:none; color:#e03c3c; font-size:12px; margin-bottom:8px; }
.dlpw_btn_wrap { display:flex; gap:8px; margin-top:6px; }
.dlpw_btn_wrap button {
    flex:1; padding:10px 0; border:none;
    border-radius:5px; font-size:14px; cursor:pointer;
}
#dlpw_confirm { background:#3c7fe0; color:#fff; }
#dlpw_confirm:hover { background:#2e6bc7; }
#dlpw_cancel  { background:#efefef; color:#444; }
#dlpw_cancel:hover { background:#e0e0e0; }
#dlpw_close_x {
    position:absolute; top:10px; right:14px;
    background:none; border:none; font-size:20px;
    color:#aaa; cursor:pointer;
}
</style>

<!-- 비밀번호 모달 HTML -->
<div id="dlpw_overlay" role="dialog" aria-modal="true" aria-labelledby="dlpw_title">
    <div id="dlpw_modal">
        <button id="dlpw_close_x" title="닫기">&times;</button>
        <h3 id="dlpw_title"><i class="fa fa-lock"></i> 첨부파일 비밀번호</h3>
        <p>첨부파일을 다운로드하려면<br>비밀번호를 입력하세요.</p>
        <input type="password" id="dlpw_input"
               placeholder="비밀번호 입력" maxlength="50" autocomplete="off">
        <div id="dlpw_error">비밀번호가 올바르지 않습니다.</div>
        <div class="dlpw_btn_wrap">
            <button id="dlpw_cancel">취소</button>
            <button id="dlpw_confirm">확인</button>
        </div>
    </div>
</div>

<script>
(function($){
    var _pendingHref = null;
    var _checkUrl    = '<?php echo addslashes($dl_pw_check_url); ?>';
    var _boTable     = '<?php echo addslashes($bo_table); ?>';
    var _wrId        = '<?php echo (int)$view['wr_id']; ?>';

    // 다운로드 링크 클릭 가로채기
    $(document).on('click', 'a.view_file_download', function(e){
        e.preventDefault();
        _pendingHref = this.href;
        openModal();
    });

    function openModal(){
        $('#dlpw_input').val('');
        $('#dlpw_error').hide();
        $('#dlpw_overlay').addClass('active');
        setTimeout(function(){ $('#dlpw_input').focus(); }, 80);
    }
    function closeModal(){
        $('#dlpw_overlay').removeClass('active');
        _pendingHref = null;
    }

    $('#dlpw_input').on('keydown', function(e){
        if (e.key === 'Enter') $('#dlpw_confirm').trigger('click');
    });

    $('#dlpw_confirm').on('click', function(){
        var pw = $('#dlpw_input').val().trim();
        if (!pw) {
            $('#dlpw_error').text('비밀번호를 입력해주세요.').show();
            return;
        }
        var $btn = $(this).prop('disabled', true).text('확인 중…');
        $.ajax({
            url     : _checkUrl,
            type    : 'POST',
            data    : { bo_table:_boTable, wr_id:_wrId, password:pw },
            dataType: 'json',
            success : function(res){
                if (res.success) {
                    closeModal();
                    location.href = _pendingHref; // 다운로드 실행
                } else {
                    $('#dlpw_error').text(res.error || '비밀번호가 올바르지 않습니다.').show();
                    $('#dlpw_input').val('').focus();
                }
            },
            error: function(){
                $('#dlpw_error').text('서버 오류가 발생했습니다.').show();
            },
            complete: function(){
                $btn.prop('disabled', false).text('확인');
            }
        });
    });

    $('#dlpw_cancel, #dlpw_close_x').on('click', closeModal);
    $('#dlpw_overlay').on('click', function(e){
        if ($(e.target).is('#dlpw_overlay')) closeModal();
    });
}(jQuery));
</script>
<?php endif; ?>

<!-- 게시물 읽기 시작 { -->
③ 첨부파일 섹션 h2 태그 — 자물쇠 아이콘 표시 원본 첨부파일 섹션 (약 110번째 줄)
Copy
// 원본
    <section id="bo_v_file">
        <h2>첨부파일</h2>
수정 후
Copy
<section id="bo_v_file">
        <h2>첨부파일<?php if ($has_file_password && !$dl_already_authed && !$is_admin) { ?>
            <small style="font-size:12px;color:#e03c3c;font-weight:normal;margin-left:6px;">
                <i class="fa fa-lock"></i> 비밀번호 보호
            </small>
        <?php } ?></h2>
3
download_pw_check.php (신규 파일)
스킨 폴더에 새로 만드는 파일 입니다.
/skin/board/{스킨명}/download_pw_check.php
Copy
<?php
/**
 * 첨부파일 다운로드 비밀번호 검증
 * 스킨 폴더에 위치: /skin/board/{스킨명}/download_pw_check.php
 *
 * wr_10 여분필드에 설정된 비밀번호를 검증 후 세션으로 다운로드 허용
 */

// 그누보드 환경 로드 (스킨 폴더 기준 상대경로로 루트 찾기)
$depth = 0;
$path  = '';
while ($depth < 10) {
    if (file_exists($path . 'common.php')) {
        break;
    }
    $path .= '../';
    $depth++;
}

if ($depth >= 10) {
    http_response_code(500);
    echo json_encode(['error' => '그누보드 루트를 찾을 수 없습니다.']);
    exit;
}

define('_GNUBOARD_', true);
require_once $path . 'common.php';

// POST 요청만 허용
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => '잘못된 요청입니다.']);
    exit;
}

header('Content-Type: application/json; charset=utf-8');

$bo_table = isset($_POST['bo_table']) ? preg_replace('/[^a-z0-9_]/i', '', $_POST['bo_table']) : '';
$wr_id    = isset($_POST['wr_id'])    ? (int)$_POST['wr_id']                                   : 0;
$password = isset($_POST['password']) ? trim($_POST['password'])                                : '';

if (!$bo_table || !$wr_id || $password === '') {
    echo json_encode(['error' => '필수 값이 누락되었습니다.']);
    exit;
}

// DB에서 해당 게시물의 wr_10(비밀번호) 조회
$write_table = $g5['write_prefix'] . $bo_table;
$row = sql_fetch("SELECT wr_10 FROM `{$write_table}` WHERE wr_id = '{$wr_id}'");

if (!$row) {
    echo json_encode(['error' => '게시물을 찾을 수 없습니다.']);
    exit;
}

$saved_pw = trim($row['wr_10']);

// wr_10이 비어있으면 비밀번호 불필요 → 바로 허용
if ($saved_pw === '') {
    echo json_encode(['success' => true, 'no_pw' => true]);
    exit;
}

// 비밀번호 비교 (평문 비교 — 필요 시 MD5/bcrypt 전환 가능)
if ($password !== $saved_pw) {
    echo json_encode(['error' => '비밀번호가 일치하지 않습니다.']);
    exit;
}

// 검증 성공 → 세션에 허용 기록 (게시물 + IP 기준)
if (!isset($_SESSION)) session_start();
$_SESSION['dl_pw_ok'][$bo_table][$wr_id] = true;

echo json_encode(['success' => true]);
exit;

/skin/board/{스킨명}/
  ├── view_skin.php       ← ①②③ 3곳 수정
  ├── write_skin.php      ← 파일루프 뒤 1곳 삽입
  ├── download_pw_check.php  ← 신규 생성

 
없지만 만들면 됩니다
하지만 우선 비밀 번호를 어떠게 고객한테 알려줄지 가 먼저 입니다
그러면 
예를 들어 
관리자가 고객에게 전화나 그런 경로로 비번을 알려 준다면
단순하게 
글쓰는 작성 자가 글을 작성할때 첩부 파일의 비번을 정하도록 비번 넣는 공간을 넣는 폼양식을 만들고
다운받을대는 그비번을 입력 받는 공간을 만들어서 확인이 될경우만 다운받는 소스가 사용되도록 
개발을 하면됩니다
그러니 
그것을 잘 생각해서 질문을 다시하시면 아마 시간 나시는 분들은 소스 코드도 만들어주실분도 있을꺼라 생각됩니다
 

답변을 작성하려면 로그인이 필요합니다.