在上一篇文章咱們講了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); } }
點擊後會出現osc的受權頁,留意url:app
用戶受權後會跳轉回咱們的網站,這時咱們能夠從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; }
完成後刷新頁面,效果如圖:
看起來很不錯,不過好像差了些什麼東西,好比想清除受權,或者換一個用戶怎麼辦? 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攻擊的。清除成功後會顯示一條通知。如圖:
好了,osc open api的受權就先到這裏了。關於refresh token和其餘的內容集中會單獨放一篇的補充。