MediaWikiAPIを利用してC♯でログインする

提供: とある社畜の頭脳整理
2019年7月26日 (金) 07:29時点におけるRin-scrooge (トーク | 投稿記録)による版 (→‎ソース)
ナビゲーションに移動 検索に移動

C#を使ってMediaWikiにログインするよ。僕が使っているMediaWikiのバージョンは1.22.2だから、これベースに説明するよ。

大まかな流れ

MediaWikiにAPIからログインするためには、ログイン用のトークンが必要だよ。ログイン用のトークンは一回ログインすると見せかけると取得できるよ。
つまり「ログインすると見せかけてログイン用のトークンを取得→ログイン」って流れになるよ。

ソース

このWikiにログインすることを想定してソースを作成したよ。
このソースは最後にログインできているか確認していないけど、みんなはちゃんと確認してね。サーバーからの応答はXMLで返却されるから分析してね。

//参照を追加するよ
using System.Net;
using System.IO;
using System.Xml;
using System.Web;

namespace WikiLib
{
    public class WikiLogin
    {
        public void Login()
        {
            //文字列を送信するために必要なインスタンスをあらかじめ生成しておくよ
            //「http://rindomain.com/rinwiki/api.php」は自分のWikiの環境に合わせて書き直すよ
            Uri l_Uri = new Uri("http://rindomain.com/rinwiki/api.php");
            CookieContainer l_CookieContainer = new CookieContainer();

            //送信文字列を生成するよ
            //「LOGIN_ID」「LOGIN_PASSWORD」は自分のWikiのIDとパスワードに書き直すよ
            StringBuilder l_StringBuilder = new StringBuilder();
            l_StringBuilder.Append("action=login");
            l_StringBuilder.Append("&lgname=LOGIN_ID");
            l_StringBuilder.Append("&lgpassword=LOGIN_PASSWORD");
            l_StringBuilder.Append("&format=xml");

            //送信文字列をバイト配列に変換するよ
            Byte[] l_ByteArray = UTF8Encoding.UTF8.GetBytes(l_StringBuilder.ToString());

            //WebRequestクラスのインスタンスを生成するよ
            HttpWebRequest l_HttpWebRequest = (HttpWebRequest)WebRequest.Create(l_Uri);
            l_HttpWebRequest.Method = "POST";
            l_HttpWebRequest.ContentType = "application/x-www-form-urlencoded";
            l_HttpWebRequest.CookieContainer = l_CookieContainer;

            //文字列を送信するよ
            Stream l_Stream = l_HttpWebRequest.GetRequestStream();
            l_Stream.Write(l_ByteArray, 0, l_ByteArray.Length);
            l_Stream.Close();

            //サーバーからの応答を受信するよ
            WebResponse l_WebResponse = l_HttpWebRequest.GetResponse();
            StreamReader l_StreamReader = new StreamReader(l_WebResponse.GetResponseStream());
            String l_ResponseString = l_StreamReader.ReadToEnd();
            l_StreamReader.Close();
            l_WebResponse.Close();

            //結果からtokenを取得するよ(フォーマットにXMLを指定しているからXML解析だね)
            String l_lgToken = String.Empty;
            XmlDocument l_XmlDocument = new XmlDocument();
            l_XmlDocument.LoadXml(l_ResponseString);
            foreach (XmlElement f_XmlElement in l_XmlDocument.DocumentElement)
            {
                l_lgToken = f_XmlElement.GetAttribute("token");
                if (l_lgToken != String.Empty)
                {
                    break;
                }
            }

            //送信文字列にトークンを追加するよ
            l_StringBuilder.Append("&lgtoken=" + l_lgToken);

            //送信文字列をバイト配列に変換するよ
            l_ByteArray = UTF8Encoding.UTF8.GetBytes(l_StringBuilder.ToString());

            //WebRequestクラスのインスタンスを生成するよ
            l_HttpWebRequest = (HttpWebRequest)WebRequest.Create(l_Uri);
            l_HttpWebRequest.Method = "POST";
            l_HttpWebRequest.ContentType = "application/x-www-form-urlencoded";
            l_HttpWebRequest.CookieContainer = l_CookieContainer;

            //文字列を送信するよ
            l_Stream = l_HttpWebRequest.GetRequestStream();
            l_Stream.Write(l_ByteArray, 0, l_ByteArray.Length);
            l_Stream.Close();

            //サーバーからの応答を受信するよ
            l_WebResponse = l_HttpWebRequest.GetResponse();
            l_StreamReader = new StreamReader(l_WebResponse.GetResponseStream());
            l_ResponseString = l_StreamReader.ReadToEnd();
            l_StreamReader.Close();
            l_WebResponse.Close();
        }
    }
}

どんなメッセージを送っているの?

一回目の送信
http://rindomain.com/rinwiki/api.php ? action=login & lgname=LOGIN_ID & lgpassword=LOGIN_PASSWORD & format=xml
二回目の送信
http://rindomain.com/rinwiki/api.php ? action=login & lgname=LOGIN_ID & lgpassword=LOGIN_PASSWORD & format=xml & lgtoken=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx