WordPressのプラグインで認証付きダウンローダー

S3に入れて置いたデータをwordpressのプラグインで認証付きのダウンローダを作れないかとの検討

プラグインは便利なので、Wordpressにログインした人のみがダウンロードできるようにしたい

こんな感じでできました

環境

    • s3にファイルを格納しておく
      wordpressはec2
      プラグインはショートコードでWordpressの固定ページなどに埋め込む
  • 仕様

    http://example.com/downloader?img=dir/file.png&token=session&userid=userid
    
    • img: S3のファイルパス
    • token: wordpressのセッションID
    • userid: wordpressのログインID(ログイン名ではなくWordpress内部でのログイン番号)

    データ

    以下に格納しておく
    s3://example/dir/file.png

    ショートコード

    固定ページをhttp://example.com/downloaderで作成し、以下を埋め込む

    [sample_downloader]
    

    プラグイン

    sample_downloaderディレクトリ以下にmain.phpで作成

    run($userid,$token,$img);
    }
    
    require_once( plugin_dir_path(__FILE__) . 'vendor/autoload.php' );
    add_shortcode('sample_downloader','sample_downloader_func');
    use Aws\S3\S3Client;
    
    
    class SampleDownloader{
        function run($userid,$token,$img){
            $bucket="example";
    
            // 認証
            $wp_token=wp_get_session_token();
            $wp_userid=wp_get_current_user();
            if($userid!=$wp_userid->ID || $wp_token!=$token){
                header("HTTP/1.1 401 Unauthorized");
                return "Authorized Error";
            }
    
            try{
    
                $s3Client = S3Client::factory(array(
                        'version' => 'latest',
                        'region'  => 'ap-northeast-1'
    	        ));
                
                $result = $s3Client->getObject([
                    'Bucket' => $bucket,
                    'Key' => $img
                ]);
                $body=$result["Body"];
    
    
                $fname=basename($img);
                $sfx=pathinfo($fname, PATHINFO_EXTENSION);
                header("HTTP/1.1 200 OK");
    
                // これで本体から出力されるHTMLをクリアする
    	    if (ob_get_length() > 0) {
                    ob_end_clean();
                }
    
                switch($sfx){
                    case "svg":
                        header('Content-Type: image/svg+xml');
                        break;
                    case "png":
                        header('Content-Type: image/pmg');
                        break;
                    case "jpg":
                    case "jpeg":
                        header('Content-Type: image/jpeg');
                        break;
                    case "gif":
                        header('Content-Type: image/gif');
                        break;
                    case "csv":
                        header('Content-Type: text/csv');
                        break;
                    case "json":
                        header('Content-Type: application/json');
                        break;
                    case "pdf":
                        header('Content-Type: application/pdf');
                        break;
                    case "xls":
                        header('Content-Type: application/vnd.ms-excel');
                        break;
                    case "xlsx":
                        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
                        break;
                    case "ppt":
                        header('Content-Type: application/vnd.ms-powerpoint');
                        break;
                    case "pptx":
                        header('Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation');
                        break;
                    case "doc":
                        header('Content-Type: application/msword');
                        break;
                    case "docx":
                        header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
                        break;
                    default:
                        header('Content-Type: application/octet-stream');
                }
    
                header('Content-Disposition: attachment; filename='.$fname);
                return $body;
    
            }catch(Exception $e){
                header("HTTP/1.1 500 Internal Server Error");
    	    return "Error";
            }
        }
    }
    ?>
    
    

    デプロイ

    zipファイルを作成しWordpressのプラグインでアップロード
    cd sample_downloader
    composer  require aws/aws-sdk-php
    cd ..
    zip -r sample_downloader.zip sample_downloader/*php sample_downloader/vendor