WordPress插件開發: 文章同步到OSC博客插件(OscPress) (二)

上一篇文章咱們講了wordpress設置頁的編碼,這篇文章裏咱們講oauth2鑑權,也就是從osc open api中獲取access token的過程。有了access token ,咱們才能調用osc的相關接口。 原理和流程請先閱讀 http://www.oschina.net/openapi/docs ,你首先須要理解這個流程,而後才能考慮用wordpress實現。其中上一節出現的php

$this->callback_url = add_query_arg('callback', 'oscpress', site_url());

就是你填在osc open api中的回調url http://域名?callback=oscpress。首先咱們向構造函數裏添加兩個新的action,前端

add_action('query_vars', array(&$this, 'add_query_vars'));

add_action("parse_request", array(&$this, 'callback'));

接下來咱們來寫回調的方法:json

// 增長一個新的公共查詢參數
public function add_query_vars($public_query_vars) {

    $public_query_vars[] = 'callback';
    return $public_query_vars;

}

// osc open api url的回傳後執行
public function callback($request)
{
    if (isset($request->query_vars['callback']) && $request->query_vars['callback'] == 'oscpress') {
        $this->_callback();
        exit();
    };

}

// 實際執行的回調
protected function _callback(){

}

add_query_vars 方法是加入了一個新的查詢參數,不用$_GET['callback'],這樣利於往後使用url重寫. 不在 callback 直接寫邏輯是爲了更清晰,在callback中負責各類前置,後置的操做,好比記錄到日誌,發送郵件等,而_callback只要集中處理回調的邏輯就好了。 接下來咱們寫一個生成引導用戶的驗證url的方法,這樣當用戶點擊這個url以後,會跳轉到osc的用戶受權頁。用戶受權完成後就能取得access token了api

// 生成引導的驗證url
protected function _generate_authorize_url() {

    $settings = (array) get_option( 'oscpress_settings' );
    if(empty($settings)) {
        return false;
    }
    $authorize_url = $this->api_site . '/action/oauth2/authorize';
    $args = array(
        'response_type' => 'code',
        'client_id' => $settings['appid'],
        'redirect_uri' => $this->_callback_url,
        'state' => wp_create_nonce($this->_state),
    );
    $authorize_url .= '?' . http_build_query($args);

    return $authorize_url;
}

而後改造一下settings_section_text,讓它顯示受權的連接瀏覽器

public function settings_section_text(){
    echo "<hr/>";
    $authorize_url = $this->_generate_authorize_url();
    if(false === $authorize_url){
        echo "<em>填寫應用的id及私鑰</em>";
    }else{
        printf("<em><a href='%s'>點擊受權</a></em>",$authorize_url);
    }

}

屏幕截圖 2016-07-08 12.49.49

點擊後會出現osc的受權頁,留意url:app

屏幕截圖 2016-07-08 12.54.13

用戶受權後會跳轉回咱們的網站,這時咱們能夠從url中得到code和state參數,接下來在回調方法中驗證state參數,並將code參數跟咱們的appid,appsecret等做爲請求參數,向接口再發送一次請求,換取access token,最後保存token。wordpress

// 實際執行的回調
protected function _callback(){
    if ( isset($_GET['code']) && isset($_GET['state']) && $this->_verify_state($_GET['state'])) {
        $code = $_GET['code'];

        $url = $this->api_site . '/action/openapi/token';
        $settings = get_option( 'oscpress_settings' );
        $args = array(
            'client_id' => $settings['appid'],
            'client_secret' => $settings['appsecret'],
            'grant_type' => 'authorization_code',
            'redirect_uri' => $this->_callback_url,
            'code' => $code,
            'dataType' => 'json'
        );

        $response = wp_remote_post($url, array('body' => $args));
        if (!is_wp_error($response) && $response['response']['code'] == 200) {
            $this->_save_token($response['body']);
            $redirect_url = admin_url('admin.php?page=oscpress_admin_settings');

            wp_redirect($redirect_url);
            printf('<script>window.location.href="%s";</script>', $redirect_url);

        } elseif (is_wp_error($response)) {
            echo "請求出錯:" . $response->get_error_message();
        } else {
            echo "未知錯誤";

        }

    } else {
        echo "回調失敗: 參數錯誤";
    }
}

這樣就完成了回調的處理。其中爲了保證瀏覽器兼容性,使用了http響應頭跳轉和前端script跳轉。 須要加入了兩個新的protected方法:函數

protected function _verify_state($state)
{

    if ($state !== wp_create_nonce($this->_state)) {
        return false;
    }
    return true;
}
protected function _save_token($token_arr)
{
    update_option('oscpress_token', $token_arr);
    update_option('oscpress_token_update_at', time());
    return true;

}

這時你再點擊設置頁面的連接,受權後跳轉回設置頁,彷佛什麼也沒發生? 其實否則,如今系統已經保存了你的access token了,只是你看不到而已,這時咱們改寫 settings_section_text的內容,顯示受權用戶的osc信息和access token. 這裏要用到osc open api獲取用戶信息接口,代碼以下:post

public function settings_section_text(){
        echo "<hr/>";
        $authorize_url = $this->_generate_authorize_url();

        if(false === $authorize_url){
            // 未填寫應用id和私鑰
            echo "<em>填寫應用的id及私鑰</em>";
        }elseif( $access_token = $this->_get_access_token() ) {
            // 已獲取access token,顯示我的信息
            $response = $this->_get_openapi_user();
            if(is_wp_error($response)) {
                echo $response->get_error_message();
            }
            $info_obj = json_decode($response['body']);

?>
            <span>

                <img align="absbottom" src="<?php echo $info_obj->avatar; ?>"/><br/>
                <a href="<?php echo $info_obj->url; ?>" target="_blank"><?php echo $info_obj->name; ?></a>
            </span>

            <p>Access Token: <?php echo $access_token;?></p><hr/>
<?php

        }else{
            // 未受權,顯示受權連接
            printf("<em><a href='%s'>點擊受權</a></em>",$authorize_url);
        }

    }

新加入兩個protected方法:網站

// 獲取存儲的access token
protected function _get_access_token(){
    $json_str = get_option('oscpress_token',false);
    if(false === $json_str) {
        return false;
    }

    $obj = json_decode($json_str);
    $update_ts = get_option('oscpress_token_update_at',0);
    if($obj->expires_in + $update_ts <= time() ){ // 過時
        return false;
    }

    return $obj->access_token;
}

// 得到用戶信息
protected function _get_openapi_user()
{
    $url = $this->api_site . '/action/openapi/user';
    $args = array(
        'access_token' => $this->_get_access_token(),
        'dataType' => 'json'
    );
    $response = wp_remote_post($url, array('body' => $args,'sslverify'=>false));
    return $response;

}

完成後刷新頁面,效果如圖:

25528645-E858-4036-90FA-5365D40F69A3  

看起來很不錯,不過好像差了些什麼東西,好比想清除受權,或者換一個用戶怎麼辦? OK,接下來咱們作一個清除受權的連接,修改一下settings_section_text方法,把清除受權的連接放進去,同時小小修改一下界面。固然這個清除只是刪除保存在本地的access token,並非從open api的服務端清除。

<span>

    <img align="absbottom" src="<?php echo $info_obj->avatar; ?>"/><br/>
    <p><a href="<?php echo $info_obj->url; ?>" target="_blank"><?php echo $info_obj->name; ?></a></p>
    <p><a href="<?php echo $this->_clear_authorize_url(); ?>">清除受權</a></p>
</span>

而後咱們寫兩個清除受權相關的函數:

// 生成取消受權url
protected function _clear_authorize_url(){
    return admin_url('admin.php?page=oscpress_admin_settings&action=clear_osc_authorize&_wpnonce=' . wp_create_nonce('clear_osc_authorize'));
}

// 清除受權信息
protected function _clear_authorize()
{
    return delete_option('oscpress_token') && delete_option('oscpress_token_update_at');
}

  最後咱們在admin_init方法加入實際清除的邏輯,放在

register_setting( 'oscpress_settings_group', 'oscpress_settings',array($this,'sanitize_callback') );這句的前面。
if($_REQUEST['action'] && $_REQUEST['action']=='clear_osc_authorize'){
    if (check_admin_referer('clear_osc_authorize')) {
        if($this->_clear_authorize()){
            add_settings_error('oscpress_settings', 'clear_osc_authorize_failed', "受權信息清除成功", 'updated');
        }
    }
}

這裏用到了check_admin_referer函數,這個是用來防csrf攻擊的。清除成功後會顯示一條通知。如圖:

clear

好了,osc open api的受權就先到這裏了。關於refresh token和其餘的內容集中會單獨放一篇的補充。

相關文章
相關標籤/搜索