たたみラボ

  • about
  • member
  • r&d
  • blog
  • tatamicast

blog

RSS

LWP::UserAgentでBasic認証サイトにアクセスする方法

icon December 20, 2006 12:25 AM by ooi1 このエントリーを含むはてなブックマーク

大井宏友です。

Webサービスを使ってマッシュアップサイトをPerlで開発したりするときに便利なCPANモジュールとしてLWP::UserAgentがありますが、 LWP::UserAgentを使ってBasic認証のかかったサイトにアクセスしようとしたときにどうやってアクセスすればいいか、 ググッて見たものの易しい解説のあるサイトはないようでしたので、紹介してみたいと思います。

マニュアルを見てみる。

LWP::UserAgentのページを見ると、こんなメソッドがあります。

$ua->get_basic_credentials( $realm, $uri, $isproxy )

This is called by request() to retrieve credentials for documents protected by Basic or Digest Authentication.

まさにこれを使えばBasic認証のサイトにもアクセスできそうなんですが…

The method should return a username and password. It should return an empty list to abort the authentication resolution attempt. Subclasses can override this method to prompt the user for the information. An example of this can be found in lwp-request program distributed with this library.

The base implementation simply checks a set of pre-stored member variables, set up with the credentials() method.

…よく分からないです(笑)。日本語訳を読んでみても、 やっぱり良く分からない…

コールバック関数を書いてみる。

何とか理解しようと何度も読み返していたとき、以下の文が目に留まりました。

Subclasses can override this method to prompt the user for the information.

開発中にプロンプトを出すようなときはサブクラスでオーバーライドできるよ、と。裏を返せば、 このコールバックメソッドをオーバーライドして、IDとパスワードをそのまま返すようにしちゃえばいいんじゃないかと思いました。

そこで、以下のようなソースを書いてみました。

  use strict;
  use LWP::UserAgent;

  my $ua = LWP::UserAgent->new;
  my $url = 'http://www.hoge.com/secret.html';
  my $res = $ua->get($url);
  print $res->content;

  #get_basic_credentialsをオーバーライド。
  #ID:moso、PW:hoyoをそのまま返す。
  package LWP::UserAgent;
  sub get_basic_credentials {
       return ('moso', 'hoyo');
  }

単純にIDとパスワードをカンマで区切って返すオーバーライドメソッドを書くだけで、アクセスに成功します。ドキュメントの難解な文と比較するとなんとカンタンなことか!

開発時のテストなどでBasic認証したサイトにアクセスする必要があった場合なんかは便利かなと思います。

(12/21追記)コメントや某所での書き込みで勉強させていただきました。もっと簡単な方法がperldocに載ってました。

  use strict;
  use LWP::UserAgent;

  my $ua = LWP::UserAgent->new;
  my $req = HTTP::Request->new(GET => 'http://www.hoge.com/secret.html');
  $req->authorization_basic('moso', 'hoyo');
  my $res = $ua->request($req);

この直後に、サブクラスでのオーバーライドの方法もあるよって書いてあって、こっちにしか目がいってなくて直前に書いてあるサンプルに気づかなかったと…失礼しました。ただGoogle検索で引っかからなかった状態だったので、このエントリーをきっかけにGoogleでも情報がGetできるようになったならそれでいいかなと思います。

COMMENTS

get_basic_credentials($realm,$uri,$isproxy)は,
$self->{'basic_authentication'}{$host_port}{$realm}
があればそこに蓄えられたデータを返し,なければ
(undef, undef)を返してます.

# $host_portは$urlのポート部分です.

んでもってデータを蓄えるのがcredentials($netloc,$realm,$uname,$pass)のようです.$netlocはポート番号ですね,きっと

December 20, 2006 11:07 AM by k.daiba  

k.daibaさんコメントありがとうございました。credentialsメソッドでの認証も試してみて本文に追記しようと思ったのですが、現時点でまだ成功していません…。

December 21, 2006 2:43 AM by 大井宏友  

POST COMMENT




(書式を変更するような一部のHTMLタグを使うことができます)

必ず利用規約に同意いただいた上で送信ください。

ページトップへ



(C) RECRUIT MEDIA COMMUNICATIONS CO., LTD.