このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
今日は mixi にログインしてみよう。
mixi のログインは、トップページのフォームに入力し、
その内容をサーバに送信することで行われる。
サーバは、認証情報を含む Cookie を返す。
それ以降は、ブラウザが Cookie を送信することで、
サーバは、ログインしていることを認識して、
自動的に個人用のトップページを返却する仕組みだ。
XMLHttpRequest でログインするためには、
まずログインフォームの動作を調べる必要がある。
メールアドレスやパスワードを送信することになるので、
SSL に対応したページでログインしたい。
https://mixi.jp を開き、HTML ソースを調べてみる。
送信フォームは <form> 要素で構成されており、
送信する内容は <input>、<button>、<textarea> のうち、
name 属性がついているものである。
では主要な部分だけ抜粋してみよう。
<form action=login.pl method=post>
<input type=hidden name=next_url value="/home.pl">
メール<INPUT type=text name=email>
パスワード<INPUT type=password name=password>
<INPUT type=checkbox name=sticky>
次回から自動的にログイン
</FORM>
送信される内容は、名前と値の組み合わせで構成される。
mixi ログインページは以下の仕様であることが分かる。
フォーム送信先: login.pl
HTTP メソッド: post
パラメータ一覧(名前: 値)
next_url: 「/home.pl」
email: 利用者の入力したメールアドレス
password: 利用者の入力したパスワード
sticky: on(チェックしない場合は送信されない)
では、XMLHttpRequest を使って送信してみよう。
========== Main.js ==========
// application/x-www-form-urlencoded でエンコードする
function _encodeForm(hash) {
var entries = [];
var prop, key, value;
for (prop in hash) {
key = encodeURIComponent(prop);
value = encodeURIComponent(hash[prop]);
entries.push(key + "=" + value);
}
return entries.join("&"); // 「;」でもいいかも
};
function main() {
// XMLHttpRequest を用意
var client = new XMLHttpRequest();
// ログイン用のパラメータを用意
var form = {
next_url: "/home.pl",
email: "自分のメールアドレス",
password: "パスワード"
};
// POST 用に符号化する
var content = _encodeForm(form);
// ログイン処理
client.open("POST", "https://mixi.jp/login.pl", false);
client.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
client.send(content);
// チェックのため、HTTP レスポンスヘッダを出力
WScript.Echo(client.getAllResponseHeaders());
// チェックのため、HTML を出力
WScript.Echo(client.responseText);
}
main();
========== end of Main.js ==========
一気に長くなったが、順にみていこう。
HTTP メソッドが POST の場合、
open メソッドの第 1 引数を POST にするだけでなく、
送信するデータの種類を意味する、「Content-Type」
HTTP リクエストヘッダを設定しなければならない。
リクエストヘッダは setRequestHeader メソッドで設定する。
フォームの場合「application/x-www-form-urlencoded」だ。
そして、send メソッドには送信されるデータを渡すのだが、
パラメータを上記形式で符号化する必要がある。
application/x-www-form-urlencoded は、
「name=value&name=value……」という形式である。
また、name や value は URL エンコードする必要がある。
その処理を行うのは、_encodeForm 関数である。
引数としてハッシュ風(連想配列風)オブジェクトを取り、
符号化された文字列を返却する。
そうすることで、パラメータを簡単に用意することができる。
var form = {
next_url: "/home.pl",
email: "自分のメールアドレス",
password: "パスワード"
};
中括弧は、オブジェクトリテラルの構文であり、
ほぼ以下と同じ意味である。
大括弧といい中括弧といい、Perl に少し似ているな。
var form = new Object();
form.next_url = "/home.pl";
form.email = "自分のメールアドレス";
form.password = "パスワード";
空のオブジェクトに対して、
プロパティを追加して利用すれば、
連想配列のような使い方ができる。
これらプロパティは、for~in 構文で列挙できるので、
_encodeForm 関数はそれを利用しているのだ。
さて、getAllResponseHeaders() メソッドは、
サーバが返却する HTTP レスポンスヘッダをそのまま返す。
ログインに成功したら Cookie が返却されるはずなので、
それを確認するために出力してみよう。
では、実行してみる。
==================================================
Date: Sat, 22 Jul 2006 13:50:33 GMT
Server: Apache
Set-Cookie: BF_SESSION=(省略); path=/
Set-Cookie: BF_STAMP=(省略); path=/
Vary: Accept-Encoding
Content-Type: text/html; charset=ISO-8859-1
Connection: close
Transfer-Encoding: chunked
<html><head><meta http-equiv="refresh" content="0;url=/check.pl?n=%2Fhome.pl"></head></html>
==================================================
このようになった。
Set-Cookie というレスポンスヘッダが確認できる。
これは、サーバが返した認証情報だ。
ちなみに、パスワードが違うなどの理由で失敗した場合、
レスポンスヘッダに Cookie はなく、
「メールアドレスもしくはパスワードが異なります。」
という文章が HTML 内に確認できる。