插件更新:保護下載鏈接

    給你的下載鏈接添加授權,方便你出售你的任何文件

    自發(fā)布插件更新檢查器庫以來,提出的最常見問題之一是:“如何保護我的下載鏈接,以便只有購買了我的插件的用戶才能下載更新?”

    在本文中,我將嘗試在使用WP Update Server提供插件更新的上下文中回答該問題。我還將從我的一個商業(yè)插件中提供一些實際示例。

    讓我們開始吧。有許多方法可以確保更新下載的安全,但是大多數方法可以歸結為:

    1. 給每個用戶某種安全令牌。這可以是會員站點的登錄名+密碼,許可證密鑰,或者更深奧的東西。
    2. 每當有人在其站點上安裝您的插件時,都要求他們輸入密鑰/登錄/以其他方式輸入。
    3. 修改插件以將令牌附加到每個更新請求。
    4. 編寫一個服務器腳本,該腳本在允許下載之前驗證令牌。

    選擇一個安全令牌

    實施前兩個步驟的方式會因插件UI以及所使用的在線商店,購物車軟件或成員資格插件而有很大差異。您可能已經存在某種客戶身份驗證機制,只需要進行一些調整即可用于更新,或者您可能需要從頭開始構建自己的身份驗證機制。這里沒有“一刀切”的解決方案。

    就個人而言,我更喜歡使用許可證密鑰。每當有人購買我的Admin Menu Editor Pro插件時,訂單處理腳本都會生成一個隨機密鑰,將其存儲在數據庫中,然后將密鑰和下載鏈接發(fā)送到客戶的電子郵件中。然后,當他們安裝插件時,將提供一個輸入許可證密鑰的鏈接。

    我不會在此處包括許可證管理代碼,因為它不在本文的討論范圍內,而是為該特定插件構建的,但是用戶界面看起來像這樣(單擊放大):

    插件更新:保護下載鏈接
    插件更新:保護下載鏈接

    將令牌添加到更新請求

    現在,我們如何將安全令牌添加到每個更新請求中?您可以使用addQueryArgFilter($callback)更新檢查器的方法來執(zhí)行此操作。回調函數將接收查詢參數的關聯數組。只需將令牌添加到列表中并返回修改后的數組即可。

    這是一個例子:

    /* ... Code that initializes the update checker ... */
     
    //Add the license key to query arguments.
    $updateChecker->addQueryArgFilter('wsh_filter_update_checks');
    function wsh_filter_update_checks($queryArgs) {
        $settings = get_option('my_plugin_settings');
        if ( !empty($settings['license_key']) ) {
            $queryArgs['license_key'] = $settings['license_key'];
        }
        return $queryArgs;
    }

    使用令牌授權下載

    最后,讓更新服務器在允許用戶下載更新之前驗證安全令牌。為此,您需要創(chuàng)建一個自定義服務器類(請參閱擴展服務器)并至少重寫該

    Wpup_UpdateServer::checkAuthorization($request)方法。這是使用此方法應做的事情:

    1. 通過使用檢索包含令牌的查詢參數$request->param('arg_name')
    2. 驗證令牌。同樣,這部分取決于您。您可以在數據庫中查找它,使用校驗和來驗證它,或進行其他操作。
    3. 如果令牌是好的,則無需執(zhí)行任何特殊操作。
    4. 如果令牌無效,請調用$this->exitWithError('Error message')以輸出錯誤并停止腳本執(zhí)行。

    以下是腳本的簡化版本,用于為Admin Menu Editor Pro實施安全更新??。它比上面的概述要先進一些,但是總體思路是相同的。

    (同樣,許可證管理超出了本文的范圍,因此,我省略了大多數與加載和驗證許可證有關的代碼。只需將verifyLicenseExists()和其他許可功能視為偽代碼。)

    class SecureUpdateServer extends Wpup_UpdateServer {
        protected $licenseServer;
     
        public function __construct($serverUrl, $licenseServer) {
            parent::__construct($serverUrl);
            $this->licenseServer = $licenseServer;
        }
     
        protected function initRequest($query = null, $headers = null) {
            $request = parent::initRequest($query, $headers);
     
            //Load the license, if any.
            $license = null;
            if ( $request->param('license_key') ) {
                $result = $this->licenseServer->verifyLicenseExists(
                    $request->slug,
                    $request->param('license_key')
                );
                if ( is_wp_error($result) ) {
                    //If the license doesn't exist, we'll output an invalid dummy license.
                    $license = new Wslm_ProductLicense(array(
                        'status' => $result->get_error_code(),
                        'error' => array(
                            'code' => $result->get_error_code(),
                            'message' => $result->get_error_message(),
                        ),
                    ));
                } else {
                    $license = $result;
                }
            }
     
            $request->license = $license;
            return $request;
        }
     
        protected function filterMetadata($meta, $request) {
            $meta = parent::filterMetadata($meta, $request);
     
            //Include license information in the update metadata. This saves an HTTP request
            //or two since the plugin doesn't need to explicitly fetch license details.
            $license = $request->license;
            if ( $license !== null ) {
                $meta['license'] = $this->licenseServer->prepareLicenseForOutput($license);
            }
     
            //Only include the download URL if the license is valid.
            if ( $license && $license->isValid() ) {
                //Append the license key or to the download URL.
                $args = array( 'license_key' => $request->param('license_key') );
                $meta['download_url'] = self::addQueryArg($args, $meta['download_url']);
            } else {
                //No license = no download link.
                unset($meta['download_url']);
            }
     
            return $meta;
        }
     
        protected function checkAuthorization($request) {
            parent::checkAuthorization($request);
     
            //Prevent download if the user doesn't have a valid license.
            $license = $request->license;
            if ( $request->action === 'download' && ! ($license && $license->isValid()) ) {
                if ( !isset($license) ) {
                    $message = 'You must provide a license key to download this plugin.';
                } else {
                    $error = $license->get('error');
                    $message = isset($error) ? $error : 'Sorry, your license is not valid.';
                }
                $this->exitWithError($message, 403);
            }
        }
    }

    來源于: https://w-shadow.com/blog/2013/03/19/plugin-updates-securing-download-links/

    隨記

    今日頭條的文章被盜素材

    2018-10-25 22:30:52

    pudding - 簡潔的Wordpress布丁主題

    2018-7-1 8:01:33

    ??
    Npcink上的部份代碼及教程來源于互聯網,僅供網友學習交流,若您喜歡本文可附上原文鏈接隨意轉載。
    無意侵害您的權益,請發(fā)送郵件至 1355471563#qq.com 或點擊右側 私信:Muze 反饋,我們將盡快處理。
    0 條回復 A文章作者 M管理員
      暫無討論,說說你的看法吧
    ?
    個人中心
    購物車
    優(yōu)惠劵
    今日簽到
    有新私信 私信列表
    搜索
    主站蜘蛛池模板: 国产福利精品一区二区| 日本成人一区二区| 国产一区内射最近更新| 伊人色综合网一区二区三区| 久久毛片一区二区| 在线观看精品一区| 精品女同一区二区| 成人精品视频一区二区三区| 亚洲AV福利天堂一区二区三| 亚洲乱色熟女一区二区三区蜜臀 | 久久精品视频一区| 亚洲欧洲精品一区二区三区| 激情无码亚洲一区二区三区| 精品一区二区三区影院在线午夜| 国产亚洲无线码一区二区| 天堂va在线高清一区| 日本人真淫视频一区二区三区| 日产一区日产2区| 免费av一区二区三区| 国产精品小黄鸭一区二区三区| 国产丝袜一区二区三区在线观看 | 麻豆va一区二区三区久久浪| 美女福利视频一区| 国产成人无码精品一区在线观看| 免费视频精品一区二区三区| 一区二区三区在线播放| 波多野结衣在线观看一区二区三区 | 色老头在线一区二区三区| 美日韩一区二区三区| 亚洲中文字幕无码一区| 亚洲熟女乱综合一区二区| 无码人妻aⅴ一区二区三区| 亚洲福利一区二区| tom影院亚洲国产一区二区| 午夜性色一区二区三区免费不卡视频| 日本不卡免费新一区二区三区| 中文字幕无码免费久久9一区9| 日韩毛片一区视频免费| 一区视频在线播放| 丰满人妻一区二区三区视频| 国内国外日产一区二区|