酢ろぐ!

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

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

|vb| ' 名前空間に 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#

|csp| // 名前空間に 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)を使ってアプリ開発する際に逆引きとしてお使いください。