読者です 読者をやめる 読者になる 読者になる

酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows Mobile(.NET Compact Framework)でCookieを使った認証の必要なサイト(mixi)へのアクセスする

多くの認証を必要としているWebサイトでは、ユーザー認証にCookieを使用しています。それらのWebサイトへWindows Mobileからプログラムでアクセスする方法についてご紹介します。

プログラムから認証を必要とするWebサイトへアクセス方法としては大きく分けて、以下の2通りがあります。

  • WebAPIを利用する
  • ユーザー情報をPOSTメソッドで投げ認証を行いhtmlを取得する

ここでご紹介する方法は、前述の分類では後者にあたる方です。.NET Frameworkの場合ですと、HttpWebRequest.CookieContainerプロパティがあり、特にCookieを意識せずとも認証を行うプログラムを作成する事が出来ます。しかし.NET Compact Frameworkには、同プロパティが存在しない為、Cookieをフレームワーク任せではなく、アプリが自前で管理する必要があります。

図-mixiの足跡ページのhtmlを表示

サンプルコードを実行した結果です。


サンプルコード

VB.NET
    ' 名前空間に Imports System.Net  を指定しておく

    ' mixiのログインURL
    Protected loginUrl As String = "http://mixi.jp/login.pl"

    ' mixiのログインURL
    Protected asiatoUrl As String = "http://mixi.jp/show_log.pl"

    ' セッションID等を格納する
    Protected cookie As String = ""

    Private Sub Login_Click(ByVal sender As System.Object, _
                            ByVal e As System.EventArgs)

        Dim id = IDTextBox.Text
        Dim pw = PWTextBox.Text

        ' ログイン情報を投げる
        Dim req = DirectCast(HttpWebRequest.Create(loginUrl), HttpWebRequest)
        With req
            .Method = "POST"
            .Headers.Add("Cookie", cookie)
            .AllowAutoRedirect = False
            .ContentType = "application/x-www-form-urlencoded"
        End With
        Dim msg = String.Format("next_url=%2Fhome.pl&email={0}&password={1}", _
                                Uri.EscapeDataString(id), _
                                Uri.EscapeDataString(pw))
        req.ContentLength = System.Text.Encoding.UTF8.GetByteCount(msg)
        Using sw As New System.IO.StreamWriter(req.GetRequestStream())
            sw.Write(msg)
        End Using

        ' レスポンスを受け取る
        Using res = DirectCast(req.GetResponse(), HttpWebResponse)

            Dim setCookie = res.GetResponseHeader("Set-Cookie")

            Dim ptn = "(?<id>BF_(SESSION|STAMP)+=[0-9a-zA-Z_]+;)"
            Dim reg As New System.Text.RegularExpressions.Regex(ptn)
            If (reg.IsMatch(setCookie)) Then
                Dim match = reg.Match(setCookie)
                While match.Success
                    cookie &= match.Groups("id").Value
                    match = match.NextMatch()
                End While
            End If
        End Using

        ' 足跡ページにアクセスする
        Dim req2 = DirectCast(HttpWebRequest.Create(asiatoUrl), HttpWebRequest)
        With req2
            .Headers.Add("Cookie", cookie)
        End With
        
        Using res = DirectCast(req2.GetResponse(), HttpWebResponse)
            Using strm As New System.IO.StreamReader(res.GetResponseStream())
        
        		    TextBox3.Text = strm.ReadToEnd()

            End Using
        End Using
    End Sub
C#
// 名前空間に Imports System.Net  を指定しておく

// mixiのログインURL
protected string loginUrl = "http://mixi.jp/login.pl";

// mixiのログインURL
protected string asiatoUrl = "http://mixi.jp/show_log.pl";

// セッションID等を格納する
protected string cookie = "";

private void Login_Click(System.Object sender, System.EventArgs e)
{
    var id = IDTextBox.Text;
    var pw = PWTextBox.Text;
    
    // ログイン情報を投げる
    var req = (HttpWebRequest)HttpWebRequest.Create(loginUrl);
    req.Method = "POST";
    req.Headers.Add("Cookie", cookie);
    req.AllowAutoRedirect = false;
    req.ContentType = "application/x-www-form-urlencoded";

    var msg = string.Format("next_url=%2Fhome.pl&email={0}&password={1}", 
                            Uri.EscapeDataString(id), 
                            Uri.EscapeDataString(pw));
    req.ContentLength = System.Text.Encoding.UTF8.GetByteCount(msg);
    using (System.IO.StreamWriter sw 
            = new System.IO.StreamWriter(req.GetRequestStream())) {
        sw.Write(msg);
    }

    // レスポンスを受け取る
    using (res == (HttpWebResponse)req.GetResponse()) {
        
        var ptn = "(?<id>BF_(SESSION|STAMP)+=[0-9a-zA-Z_]+;)";
        
        var setCookie = res.GetResponseHeader("Set-Cookie");
        System.Text.RegularExpressions.Regex reg 
          = new System.Text.RegularExpressions.Regex(ptn);
        if ((reg.IsMatch(setCookie))) {
            var match = reg.Match(setCookie);
            while (match.Success) {
                cookie += match.Groups("id").Value;
                match = match.NextMatch();
            }
        }
    }

    // 足跡ページにアクセスする
    var req2 = (HttpWebRequest)HttpWebRequest.Create(asiatoUrl);
    req2.Headers.Add("Cookie", cookie);
    
    using (res == (HttpWebResponse)req2.GetResponse()) {
        using (System.IO.StreamReader strm 
                = new System.IO.StreamReader(res.GetResponseStream())) {

            // 足跡ページのHtmlをレスポンストリームから読み出し
            TextBox3.Text = strm.ReadToEnd();
        }
    }
}

認証を行うURLに対して、ユーザーIDとパスワード(とその他諸々の付加情報)をPOSTし、認証済みのセッションIDが格納されているCookieを利用しています。
ここでは「mixi」を例にして、ログインし足跡ページを表示するまでの処理を書きました。

関連記事

Windows Mobile(.NET Compact Framework)を使ってアプリ開発する際に逆引きとしてお使いください。