LoginSignup
7
5

More than 5 years have passed since last update.

C# で Wordpress の OAuth 認証をする

Posted at

C# で Wordpress の OAuth 認証をする

Wordpress の REST API を C# から叩くため、OAuth 認証をしてアクセストークンを取得します。

プラグインのインストール

OAuth 認証をするためには、Wordpress に以下の plugin をインストールします。
プラグインの検索では出てこないため、github から zip をダウンロードしてきてインストールする必要があります。

WP REST API - OAuth 1.0a Server
https://github.com/WP-API/OAuth1

OAuth 2.0 認証ができるプラグインもあるようですが、今回は公式から出ている 1.0a のものを使います。

Client Key と Client Secret を作成する

プラグインをインストールすると、「ユーザ」ところに「Application」という項目が出てきます。
01.jpg

ここで Client Key と Client Secret を作成します。
Callback は必須だったので、適当な URL を入れています。
02.jpg

"Save Consumer" をすると Client Key と Client Secret が作成されます。

OAuth 認証をする

ここからは C# のクライアント側の処理になります。
Google 製の OAuthBase.cs を利用するのでプロジェクトに追加しておいてください。
公式サイトからは消えてしまっているようでしたが、ぐぐるといくつか出てきます。
追加した際、System.Web を参照に加えておかないと HttpUtility でエラーになります。

OAuth 認証は
1. リクエストトークンの取得
2. 認証
3. アクセストークンの取得

の3段階にわかれているので、順番に行っていきます。

それぞれのエンドポイント URL は http://vccw.dev/wp-json/ にアクセスすると以下のように出てきます。
逆に、authentication が空になっている場合は OAuth プラグインが有効になっていません。
03.jpg

リクエストトークンの取得

class OAuthSample
{
    static readonly string CLIENT_KEY = "v9T4twiheMxl";
    static readonly string CLIENT_SECRET = "qZccFO1eVR1EndpnHZhqRkT98Y5u6rPGylnvjskFMA46bLL5";

    static readonly string BASE_URL = "http://vccw.dev/";
    static readonly string REQUEST_URL = BASE_URL + "oauth1/request";
    static readonly string AUTHORIZE_URL = BASE_URL + "oauth1/authorize";
    static readonly string ACCESS_TOKEN_URL = BASE_URL + "oauth1/access";

    public void Authentication()
    {
        var oauth = new OAuthBase();
        var nonce = oauth.GenerateNonce();
        var timestamp = oauth.GenerateTimeStamp();

        string normalizedUrl, normalizedReqParams;
        var signature = oauth.GenerateSignature(
            new Uri(REQUEST_URL),
            CLIENT_KEY,
            CLIENT_SECRET,
            null,
            null,
            "GET",
            timestamp,
            nonce,
            out normalizedUrl,
            out normalizedReqParams);

        var requestTokenUrl = normalizedUrl + "?" + normalizedReqParams + "&oauth_signature=" + signature;
        var client= new WebClient();
        var token = Encoding.ASCII.GetString(client.DownloadData(requestTokenUrl ));
    }
}

CLIENT_KEY と CLIENT_SECRET から signature を計算し、必要なパラメータとともにリクエストトークンのエンドポイントへ投げます。
パラメータ文字列も OAuthBase.cs 内で勝手に作ってくれます。
得られた token がリクエストトークンで以下のような文字列になっています。

oauth_token=tyNCKaL3WAJXib5SI6jCnr4P&oauth_token_secret=1GiImP2XBacmk4FhcEFtqqENs3Bt6Q1m3zDf5s0Rk2kDJyTF&oauth_callback_confirmed=true

このままでは使いにくいので、適当にパースして oauth_token と oauth_token_secret の値を取っておきます。

認証

得られた oauth_token と oauth_token_secret を使って認証をします。

class OAuthSample
{
    static readonly string BASE_URL = "http://vccw.dev/";
    static readonly string AUTHORIZE_URL = BASE_URL + "oauth1/authorize";

    public void Authentication()
    {
        ...

        var auth_url = AUTHORIZE_URL +
                        "?oauth_token=" + tokenParam["oauth_token"] +
                        "&oauth_token_secret=" + tokenParam["oauth_token_secret"];

        System.Diagnostics.Process.Start(auth_url);
    }
}

oauth_token と oauth_token_secret から作成した URL にブラウザでアクセスします。
すると以下のような画面にが出てくるので "Authorize" を押します。
04.jpg
Authorize すると以下のように認証トークンが取得できます。
05.jpg

アクセストークンの取得

得られた認証トークンを使ってアクセストークンを取得します。
GET リクエストでもできると思うのですが、何故か手元の環境ではパラメータが正しく認識されなかったので POST でリクエストを投げています。
しばらくハマりましたが、signature は URL エンコードしておかないと + が消えてエラーになるので注意。


class OAuthSample
{
    static readonly string BASE_URL = "http://vccw.dev/";
    static readonly string ACCESS_TOKEN_URL = BASE_URL + "oauth1/access";

    public void Authentication()
    {
        ...

        signature = oauth.GenerateSignature(
            new Uri(ACCESS_TOKEN_URL),
            CLIENT_KEY,
            CLIENT_SECRET,
            tokenParam["oauth_token"],
            tokenParam["oauth_token_secret"],
            "POST",
            timestamp,
            nonce,
            verification_token,
            out normalizedUrl,
            out normalizedReqParams
            );

        var params = normalizedReqParams + "&oauth_signature=" + HttpUtility.UrlEncode(signature);

        var ps = new NameValueCollection();
        foreach(var param in params.Split('&'))
        {
            var data = param.Split('=');
            ps.Add(data[0], data[1]);
        }
        var access_token = client.UploadValues(ACCESS_TOKEN_URL, ps);
    }
}

問題なくリクエストが通れば、以下の様な形式でアクセストークンが取得できます。

oauth_token=tNo6uEm22jk3VplA7QQ1D1B7&oauth_token_secret=XVPdQboBzGfFXelXIzfVWQpY0Ox8YDTivbjHcv3Kgj0tD8vM

これで OAuth 認証は完了です。
以降はこのアクセストークンを使ってリクエストが投げられます。

アクセストークンを使って REST API を叩く

アクセストークンを使って Wordpress に新規投稿をしてみます。

class OAuthSample
{
    static readonly string CLIENT_KEY = "v9T4twiheMxl";
    static readonly string CLIENT_SECRET = "qZccFO1eVR1EndpnHZhqRkT98Y5u6rPGylnvjskFMA46bLL5";
    static readonly string ACCESS_TOKEN = "tNo6uEm22jk3VplA7QQ1D1B7";
    static readonly string ACCESS_TOKEN_SECRET = "XVPdQboBzGfFXelXIzfVWQpY0Ox8YDTivbjHcv3Kgj0tD8vM";

    static readonly string BASE_URL = "http://vccw.dev/";
    static readonly string REST_URL = BASE_URL + "wp-json/wp/v2/";
    static readonly string POST_URL = REST_URL + "posts/";

    public void PostRequest()
    {
        var oauth = new OAuthBase();
        var nonce = oauth.GenerateNonce();
        var timestamp = oauth.GenerateTimeStamp();

        string normalizedUrl, normalizedReqParams;
        var sign = oauth.GenerateSignature(
            new Uri(post_url),
            CLIENT_KEY,
            CLIENT_SECRET,
            ACCESS_TOKEN,
            ACCESS_TOKEN_SECRET,
            "POST",
            timestamp,
            nonce,
            out normalizedUrl,
            out normalizedReqParams);

        var header = $"OAuth oauth_consumer_key=\"{CLIENT_KEY}\", "
                    + $"oauth_nonce=\"{nonce}\", "
                    + $"oauth_signature=\"{HttpUtility.UrlEncode(signature)}\","
                    + $"oauth_signature_method=\"HMAC-SHA1\","
                    + $"oauth_timestamp=\"{timestamp}\", "
                    + $"oauth_token=\"{ACCESS_TOKEN}\", "
                    + $"oauth_version=\"1.0\"";

        client.Headers[HttpRequestHeader.Authorization] = header;
        client.Encoding = Encoding.UTF8;
        client.Headers[HttpRequestHeader.ContentType] = "application/json;charset=UTF-8";
        client.Headers[HttpRequestHeader.Accept] = "application/json";

        var client = new WebClient();
        var responce = client.UploadString(POST_URL, "{\"title\":\"test post\", \"status\":\"publish\"}");
    }
}

Authentication ヘッダが長くて面倒ですが、こんな感じで使います。

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5