WordPress REST APIで投稿するには認証が必要となる。
認証には、クッキーベース、ベーシック認証ベース、OAuth認証ベース、の方法があるが、
その中でも一番セキュアな、OAuthでの認証を行ってみる。
環境情報など
試した環境など。
- PHP 5.6
- WordPress ver.4.5.3
- WP REST API ver.2.0-beta13.1
- WP REST API – OAuth 1.0a Server ver.0.2.1
- ドメイン :
http://wprest.local
WordPressのセットアップ
WP REST API
WordPress REST API (Version 2) — WordPress Plugins
プラグインの新規追加から検索すれば出てくる。
そこからインストールして、有効化すればOK。
WP REST API – OAuth 1.0a Server
WP-API/OAuth1: OAuth server implementation for WP API
上記からzipをダウンロードし、プラグイン->新規追加
からzipをアップロードし、その後有効化する。
ユーザー項目に、Applicatons
が増えていれば正しく有効化出来ている。
また、WP REST APIを追加していれば、/wp-json/
にアクセスした際にOAuth認証するためのURLが表示されるようになる。
1
2
3
4
5
6
7
8
| authentication: {
oauth1: {
request: "http://wprest.local/oauth1/request",
authorize: "http://wprest.local/oauth1/authorize",
access: "http://wprest.local/oauth1/access",
version: "0.1"
}
},
|
アプリケーションの追加
ユーザー -> Applications
を開き、Add Application
をクリック。それぞれの項目を適当に入力する。
Callback
の値は適当に/test
などと入れておいた。
本来であれば、承認が行われた後にcallbackで指定されたURLへリダイレクトがかかるはずなのだが、不具合なのか動作しなかった。
Add Consumer
をクリックするとClient Key
とClient Secret
が生成される。
|
項目 |
内容 |
|
Client Key |
RY5OpVfznCzY |
|
Client Secret |
8HHflSELMukNNE6NxFNFeJDAsoHA7Dhjkb6wXFoxduMykAwo |
PHPで接続
環境変数
環境変数に上記で取得したアプリケーションのキーなどを追加して使用することにする。
1
2
| WP_CLIENT_KEY=RY5OpVfznCzY
WP_CLIENT_SECRET=8HHflSELMukNNE6NxFNFeJDAsoHA7Dhjkb6wXFoxduMykAwo
|
PECL oauth
Oauth 1.0a
での認証を行うために、PECL oauthライブラリを使用する。
公式のマニュアル: PHP: OAuth – Manual
PECL::OAuthは、OAuthコンシューマやプロバイダの機能をphpで手軽に実装できるようにする拡張モジュールです。
http://blog.flatlabs.net/20100611_062745/
HerokuでPHPの拡張モジュールを利用する場合には、composerで追加する事が出来る。
以下のコマンドで追加が可能。
1
| $ composer require ext-oauth
|
参考: Heroku PHP Support | Heroku Dev Center
ローカル環境などのサーバに追加する場合は、直接インストールしてやる必要がある。
参考: PECL/oauthの導入方法 | 配電盤
今回はローカル環境には、Scotchboxを利用しているので、Ubuntuにインストール方法をメモしておく。
インストールと設定
上記参考サイトの通りだが、そのままoauth
をインストールしようとするとバージョンでエラーが出る。
oauth
の最新版では、PHP7.0以上のみサポートされているようなので、PHP5.6対応のバージョンを明示的に指定してやる必要がある。
1
2
| $ sudo apt-get install apache2 php5 php5-dev php-pear libpcre3-dev make
$ sudo pecl install oauth-1.2.3
|
最後に書かれている通り、php.ini
に追記する。
/etc/php5/apache2/php.ini
apache再起動。
1
| $ sudo service apache2 restart
|
phpinfo
でOAuthが有効と表示されていれば完了。
トークンの取得
今回の承認などに必要なPHPファイルは全て同一ドメイン・同一階層に置くものとする。
OAuth1.0aの承認フローなどの動きは以下がとても参考になった。
参考: WP REST API の OAuth 認証の方法と何が起こっているのかとなぜそんなことをしているのか – Shinichi Nishikawa's
コード
参考 : Tumblr API OAuth認証の方法(PHPサンプル付き) – Qiita
こちらのコードをほぼそのまま利用させてもらった。
login.php
1
2
3
4
5
6
7
8
9
10
| <?php
require_once './OAuthSample.php';
$oauth_sample = new OAuthSample();
try {
// リクエストトークンの取得とリダイレクト開始
$oauth_sample->goToAuthorize();
} catch (\Exception $e) {
// エラー処理
}
|
OAuthSample.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
| <?php
/**
* Tumblr OAuth認証実装サンプル
*
* @author newton
*/
class OAuthSample
{
const REQUEST_TOKEN_URL = 'http://wprest.local/oauth1/request';
const AUTHORIZE_URL = 'http://wprest.local/oauth1/authorize';
const ACCESS_TOKEN_URL = 'http://wprest.local/oauth1/access';
public $CONSUMER_KEY = '';
public $CONSUMER_SECRET = '';
/**
* コントストラク
* セッションの初期化をやる
*/
public function __construct()
{
$this->CONSUMER_KEY = getenv('WP_CLIENT_KEY');
$this->CONSUMER_SECRET = getenv('WP_CLIENT_SECRET');
if (!isset($_SESSION)) {
session_start();
}
}
/**
* リクエストトークンの取得~リダイレクト
*/
public function goToAuthorize()
{
$oauth = new \OAuth($this->CONSUMER_KEY, $this->CONSUMER_SECRET);
// リクエストトークン取得
$request_token = $oauth->getRequestToken(self::REQUEST_TOKEN_URL);
if (!$request_token) {
throw new Exception('リクエストトークンの取得に失敗');
}
// リクエストトークンをセッションに保存する
$_SESSION['request_token'] = $request_token['oauth_token'];
$_SESSION['request_token_secret'] = $request_token['oauth_token_secret'];
$params = ['oauth_token' => $request_token['oauth_token']];
$path = self::AUTHORIZE_URL . '?' . http_build_query($params);
$this->redirect($path);
}
/**
* アクセストークンの取得
* コールバック後にコールされる用
*
* @return array アクセストークンのセットされたハッシュ
*/
public function getAccessToken()
{
$oauth = new \OAuth(self::CONSUMER_KEY, self::CONSUMER_SECRET);
// アクセストークンの取得
$oauth->setToken($_SESSION['request_token'], $_SESSION['request_token_secret']);
$access_token = $oauth->getAccessToken(self::ACCESS_TOKEN_URL, $_GET['oauth_verifier']);
if (!$access_token) {
throw new \Exception('アクセストークンの取得に失敗');
}
return $access_token;
}
/**
* リダイレクト
*
* @param string $path リダイレクト先URL
* @param int $status ステータスコード
*/
private function redirect($path, $status = 302)
{
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
header("Location: {$path}", true, $status);
exit;
}
}
|
callback.php
1
2
3
4
5
6
7
8
9
10
11
| <?php
require_once './OAuthSample.php';
$oauth_sample = new OAuthSample();
try {
// アクセストークンの取得
$access_token = $oauth_sample->getAccessToken();
var_dump($access_token);
} catch (\Exception $e) {
// エラー処理
}
|
承認
作成したlogin.php
へアクセスすると(ログインしていない場合はログイン画面が表示されログイン後に)承認のページが表示される。
Authorize
をクリックすると、許可されて、承認コードが表示される。
(ここでコードが表示されるのではなく、コールバックURLへリダイレクトが行われるのが通常のフローだと思う)
Your verification token is j0lHiEOe07gOtUOkEA6J1q00
アクセストークンの取得
コールバックが自動で行われないので、作成したcallback.php
へ直接アクセスしてやる。
http://wprest.local/callback.php?oauth_verifier=j0lHiEOe07gOtUOkEA6J1q00
こうすることで、アクセストークンを取得できた。
1
2
3
4
5
6
| array(2) {
["oauth_token"]=>
string(24) "UTriXsugNS1c0ddCc1UBuMPj"
["oauth_token_secret"]=>
string(48) "6GAHfovkjdSPm2LZbtf06vV3ouBML8WaqiwPIfCGsGY0jVHA"
}
|
実際に投稿などをPOSTするには、アプリケーションのカスタマーキーなども合わせて必要になる。
まとめると以下となる。
|
項目 |
内容 |
|
Client Key |
RY5OpVfznCzY |
|
Client Secret |
8HHflSELMukNNE6NxFNFeJDAsoHA7Dhjkb6wXFoxduMykAwo |
|
OAuth Token |
UTriXsugNS1c0ddCc1UBuMPj |
|
OAuth Token Secret |
6GAHfovkjdSPm2LZbtf06vV3ouBML8WaqiwPIfCGsGY0jVHA |
投稿
さて、ここまででアクセストークンなど投稿に必要なものが一通り揃ったので、ようやく新規投稿の準備が整った。
投稿は簡単で、今までと同じようにトークンなどをセットして指定のエンドポイントへパラメータを投げてやるだけでおyい。
エンドポイントは、新規投稿となるので、http://wprest.local/wp-json/wp/v2/posts
となる。
これも、先ほどのTumblerへの投稿を書いた記事を参考にさせてもらった。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| <?php
$consumer_key = 'RY5OpVfznCzY';
$consumer_secret = '8HHflSELMukNNE6NxFNFeJDAsoHA7Dhjkb6wXFoxduMykAwo';
$oauth_token = 'UTriXsugNS1c0ddCc1UBuMPj';
$oauth_token_secret = '6GAHfovkjdSPm2LZbtf06vV3ouBML8WaqiwPIfCGsGY0jVHA';
$response = '';
try {
$oauth = new \OAuth($consumer_key, $consumer_secret);
$oauth->setToken($oauth_token, $oauth_token_secret);
//POST
$params = ['title' => 'From PHP'];
$oauth->fetch('http://wprest.local/wp-json/wp/v2/posts', $params, OAUTH_HTTP_METHOD_POST);
$response_info = $oauth->getLastResponseInfo();
if ($response_info['http_code'] == 201) {
$response = json_decode($oauth->getLastResponse(), true);
}else{
throw new \Exception('記事の投稿に失敗');
}
} catch (\Exception $e) {
// エラー処理
var_dump($e);
}
// 結果をダンプ
var_dump($response);
|
これでこのファイルへアクセスすると、無事、新規投稿が行われる。
以上。