2010年11月28日日曜日
HMAC方式で認証用のハッシュを生成するメモ
HMAC(Keyed-Hashing for Message Authentication Code)とは?
HMACはハッシュ(Message Digest)生成アルゴリズムで、MD5やSHA1、SHA2等と組み合わせて使う。(それぞれ「HMAC-MD5」「HMAC-SHA1」などと呼ばれる。)
なぜ認証用のハッシュがHMACでなければいけないのか?
HMACでないハッシュ関数を認証用のハッシュ(トークン)生成に使うと、秘密鍵を知らなくても任意のハッシュを生成できるケースがあるらしい。(参考:Kazuho@Cybozu Labs: Re: はてな認証 API)
よく理解していないけど、ハッシュアルゴリズムがデータブロック単位で処理することに起因している?
暗号化においてCBCでIVが固定の場合と同じような問題?(参考:floatingdays: PHPで AES方式 (Rijndael-128)で暗号化するメモ)
それに対してHMACでは、変換元の値とは別に指定する秘密鍵組み合わせることにより、上記の問題を回避しているらしい。(参考:HMAC: Keyed-Hashing for Message Authentication)
HMAC方式でハッシュを生成する方法
今どきのプログラム環境は言語レベルで実装してるみたい。
PHP 5.1.2以降の場合
→ HMAC 方式を使用してハッシュ値を生成する - PHP 5.3 日本語マニュアル
PHP 5.1.1以前の場合、外部ライブラリとしてmhashが必要 (参考:導入 - PHP 5.3 日本語マニュアル)
→ ハッシュ値を計算する - PHP 5.3 日本語マニュアル
Javaの場合
→ 試験管のなかのコード :: JDK 1.4.x 環境で HMAC with the SHA256 を使用する方法
参考:
2010年11月21日日曜日
PHPで 「Webページの有効期限が切れてます」となる時の傾向と対策
PHPでフォーム等を作った場合、Webブラウザの戻るボタンやJavaScriptのhistory.back()で前のページに戻った時に「Webページの有効期限が切れてます」と表示されることがある。

上記はIEの場合で、ブラウザによって少し挙動が違う(下記)。
いずれもページを更新(リロード)するとサーバにPOSTが再送信され、ページが表示される。
犯人はだれだ?
原因は、PHPでSESSIONを使うと(デフォルト設定では)自動でキャッシュ制御用のHTTPヘッダーが送出され、それによりクライアント側のキャッシュが使用不可にされるため。(参考:floatingdays: PHPでブラウザキャッシュを有効にする)
つまり、下記条件を全て満たした場合にこの現象が発生する。
じゃあどうすればいいの?
対策として有名なのは、session_start()する前に、session_cache_limiter('none')とすること。
または、php.ini等でsession.cache_limiterに"none"を設定しても同じことになる。(おそらく元ネタはこのあたりだろう → PHP: session_cache_limiter - Manual )
実際にこれで問題は解決する。
異論反論オブジェクション! [shut very bad!]
しかし、「PHP/「ページの有効期限切れ」対策 - Glamenv-Septzen.net」によると、これはPHPが想定しているパラメータではなく、お行儀のよいやり方ではないらしい。
'none'というパラメータは正しいパラメータではなく、それゆえに何もHTTPヘッダーを送出しないという挙動になるらしい。
(ただし、もし「規定外のパラメータはスルーする」というのが意図した仕様だとしたら、'none'でも何でも「正しいパラメータ」だけど。)
上記の記事ではsession_cache_limiter('none')ではなくsession_cache_limiter('private_no_expire')を推奨している。
「「ページの有効期限切れ」をsession_cache_limiter()で解決 - shinyanakaoのよすがブログ」でも同様にprivate_no_expireを推奨している。
しかし、実際にsession_cache_limiter('private_no_expire')を使うと、やはり余分なHTTPヘッダーが送出される。
private_no_expireの場合、(privateに比べて)Expiresが送出されなくなるが、「Cache-Control: max-age=(session.cache_expire ぶんだけ未来)」が送出されるため、やはりブラウザに影響が出てしまう。(参考:現在のキャッシュリミッタを取得または設定する - PHP 5.3 日本語マニュアル)
Firefoxでは問題ないが、IEだとリロード時にもキャッシュを使ってしまい、サーバからのリロードができなくなるようだ。(参考:Webアプリケーション開発ラボ by NPO情報活用センター - PHP:キャッシュ問題について。、PHP Tips|ワークスポット・ジェーピー)
おそらくsession.cache_expireで設定されている期間はキャッシュが有効になるのだろう。(Expiresでそう指定しているのだから、IEは悪くない。)
なので、お行儀が悪くてもsession_cache_limiter('none')を使うしかないのでは?('none'じゃなくて'hoge'でも'hage'でも「正しい」パラメータ以外なら何でもいいけど。)
新たな選択肢
しかし、こういう手もあるよ。
これにより、session_start()のHTTPヘッダー送出を上書きし、結果的に何も送出しない。
session_cache_limiter('none')より冗長だが、明示的という意味ではいいかもしれないと思っている。
(キャッシュを有効にしたい場合にも応用が効く。)
余談
上記のようにブラウザキャッシュの無効化を無効化すると、当然ながらSESSIONの最新情報が反映されていないブラウザキャッシュをブラウザが表示してしまうので注意。
(2011/1/7 追記)
IEはキャッシュがあり、かつ、そのキャッシュがExpiresを何も指定されていないと、アドレスバーにURLを直接入力された場合やリダイレクトした場合などにサーバにアクセスせずにキャッシュの方を使ってしまう。(Firefoxはその場合もサーバにアクセスしてくれる。)
ブラウザの履歴機能を使うためにキャッシュはさせたいが、上記の場合にはサーバにアクセスさせたい場合は、Expiresで-1を指定すると良いようだ。
(追記終わり)
上記はIEの場合で、ブラウザによって少し挙動が違う(下記)。
いずれもページを更新(リロード)するとサーバにPOSTが再送信され、ページが表示される。
- IE
- 上記(IE8の例)のような画面が表示される。
- Firefox
- 「このページを表示するにはフォームデータを再度送信する必要があります。フォームデータを再送信すると以前実行した検索、投稿や注文などの処理が繰り返されます。」という確認ダイアログが表示され、「再送信」ボタンと「キャンセル」ボタンが表示される。「再送信ボタン」をクリックするとページが表示される。
- Chrome
- 「フォーム再送信の確認
このウェブページを正しく表示するには、先ほど入力したデータが必要です。データをもう一度送信することは可能ですが、このページで行った操作をすべて繰り返すことになります。データを再送信してこのページを表示する場合は [再読み込み] をクリックしてください。」というメッセージのみの画面が表示される。 - Safari
- このようなダイアログが表示される。(Windows版で確認。Mac版は分からない。)
犯人はだれだ?
原因は、PHPでSESSIONを使うと(デフォルト設定では)自動でキャッシュ制御用のHTTPヘッダーが送出され、それによりクライアント側のキャッシュが使用不可にされるため。(参考:floatingdays: PHPでブラウザキャッシュを有効にする)
つまり、下記条件を全て満たした場合にこの現象が発生する。
- HTTP POSTで遷移してきた。
- SESSIONを使っている。(session_start()してるか、php.ini等でsession.auto_start=1に設定している。)
- 次のページに行ってから、ブラウザの履歴機能(JavaScriptのhistory.back()を含む)で戻ってきた。
じゃあどうすればいいの?
対策として有名なのは、session_start()する前に、session_cache_limiter('none')とすること。
session_cache_limiter('none');これにより、SESSIONを使っても余計なHTTPヘッダーが送出されなくなる。
session_start();
または、php.ini等でsession.cache_limiterに"none"を設定しても同じことになる。(おそらく元ネタはこのあたりだろう → PHP: session_cache_limiter - Manual )
実際にこれで問題は解決する。
異論反論オブジェクション! [shut very bad!]
しかし、「PHP/「ページの有効期限切れ」対策 - Glamenv-Septzen.net」によると、これはPHPが想定しているパラメータではなく、お行儀のよいやり方ではないらしい。
'none'というパラメータは正しいパラメータではなく、それゆえに何もHTTPヘッダーを送出しないという挙動になるらしい。
(ただし、もし「規定外のパラメータはスルーする」というのが意図した仕様だとしたら、'none'でも何でも「正しいパラメータ」だけど。)
上記の記事ではsession_cache_limiter('none')ではなくsession_cache_limiter('private_no_expire')を推奨している。
「「ページの有効期限切れ」をsession_cache_limiter()で解決 - shinyanakaoのよすがブログ」でも同様にprivate_no_expireを推奨している。
しかし、実際にsession_cache_limiter('private_no_expire')を使うと、やはり余分なHTTPヘッダーが送出される。
private_no_expireの場合、(privateに比べて)Expiresが送出されなくなるが、「Cache-Control: max-age=(session.cache_expire ぶんだけ未来)」が送出されるため、やはりブラウザに影響が出てしまう。(参考:現在のキャッシュリミッタを取得または設定する - PHP 5.3 日本語マニュアル)
Firefoxでは問題ないが、IEだとリロード時にもキャッシュを使ってしまい、サーバからのリロードができなくなるようだ。(参考:Webアプリケーション開発ラボ by NPO情報活用センター - PHP:キャッシュ問題について。、PHP Tips|ワークスポット・ジェーピー)
おそらくsession.cache_expireで設定されている期間はキャッシュが有効になるのだろう。(Expiresでそう指定しているのだから、IEは悪くない。)
なので、お行儀が悪くてもsession_cache_limiter('none')を使うしかないのでは?('none'じゃなくて'hoge'でも'hage'でも「正しい」パラメータ以外なら何でもいいけど。)
新たな選択肢
しかし、こういう手もあるよ。
session_start();header()でセミコロンの右に何も書かないと、PHPは何も送出しないようだ。
header('Expires:'); //下記「余談」の追記も参照
header('Cache-Control:');
header('Pragma:');
これにより、session_start()のHTTPヘッダー送出を上書きし、結果的に何も送出しない。
session_cache_limiter('none')より冗長だが、明示的という意味ではいいかもしれないと思っている。
(キャッシュを有効にしたい場合にも応用が効く。)
余談
上記のようにブラウザキャッシュの無効化を無効化すると、当然ながらSESSIONの最新情報が反映されていないブラウザキャッシュをブラウザが表示してしまうので注意。
(2011/1/7 追記)
IEはキャッシュがあり、かつ、そのキャッシュがExpiresを何も指定されていないと、アドレスバーにURLを直接入力された場合やリダイレクトした場合などにサーバにアクセスせずにキャッシュの方を使ってしまう。(Firefoxはその場合もサーバにアクセスしてくれる。)
ブラウザの履歴機能を使うためにキャッシュはさせたいが、上記の場合にはサーバにアクセスさせたい場合は、Expiresで-1を指定すると良いようだ。
header('Expires: -1');ログイン管理をする場合などはこれをやっておいた方が良さそう。
(追記終わり)
また、POSTのパラメータに「チケット」(=ワンタイムトークン)を入れることによる二重POST防止を推奨するのは正しい。というか二重POSTを確実に防ぎたいと思ったらこれしかない。
2010年11月16日火曜日
大手サイトがやっている自サイト専用のURL短縮サービス
思いつくものをまとめてみた。
bit.lyによる独自ドメインURL短縮サービスで日本人にあまり馴染みのないもの(NY Timesとか)は除外した。
日経新聞のサブドメインを使うやり方は好感が持てる。
Bingはよく考えたら自サイト専用じゃないけどまあいいや。
ところでyhoo.itはYahoo! Italia(it.yahoo.com)と間違えそう。
bit.lyによる独自ドメインURL短縮サービスで日本人にあまり馴染みのないもの(NY Timesとか)は除外した。
サイト | 短縮URL | 備考 |
Google Maps FeedBurner | goo.gl | Google Mapsは goo.gl/maps/xxxx FeedBurnerは goo.gl/fb/xxxx その他のサイトの場合、 goo.gl/xxxx |
YouTube | youtu.be | 後ろに動画のIDを付けると、その動画の短縮URLになる。 例: http://youtu.be/4qCbiCxBd2M |
Yahoo! | yhoo.it | powered by bit.ly uk.yahoo.comやfr.yahoo.comは短縮してくれるが、 yahoo.co.jpは対象外。なぜかtw.yahoo.comも対象外。 |
Flickr | flic.kr | |
Delicious | icio.us | ドメインハックの先駆者がこんな形で再利用されるとは。 |
Bing | binged.it | 短縮URLは既に機能しているが、 URL生成はまだプライベートBeta。 |
Amazon (USのみ) | amzn.com | 後ろにASINを付けると、その商品ページの短縮URLになる。 例: http://amzn.com/B002FQJT3Q Kindleの場合、「amzn.com/k/xxx」のようだ。 アソシエイトはできるのかな? |
Amazon | amzn.to | powered by bit.ly こちらはamazon.co.jpも対象。 |
Facebook | fb.me | |
Twitter | t.co | |
foursquare | 4sq.com | |
MySpace | mysp.ac | powered by bit.ly |
Ustream | ustre.am | |
Dailymotion | dai.ly | powered by bit.ly |
Scribd | scr.bi | powered by bit.ly |
楽天 | r10.to | どこで生成できるか分からなかった |
mixi | mixi.at | |
ニコニコ動画 | nico.ms | |
はてな | htn.to | |
PIXIV | p.tl | |
日経新聞 | s.nikkei.com | powered by bit.ly |
日経新聞のサブドメインを使うやり方は好感が持てる。
Bingはよく考えたら自サイト専用じゃないけどまあいいや。
ところでyhoo.itはYahoo! Italia(it.yahoo.com)と間違えそう。
(2011/3/21 追記)
htn.toは、はてなブックマークだけでなく、はてな全般で使われているみたい。(これを書いた後で変わった?)また、bit.ly proを使ってるわけではないようだ。
参考:
Bit.ly、月間47億クリック。Pro版も好調、Yahoo、MySpaceらも採用
bit.ly | Basic | a simple URL shortener
JSTwi
(追記終わり)
参考:
Bit.ly、月間47億クリック。Pro版も好調、Yahoo、MySpaceらも採用
bit.ly | Basic | a simple URL shortener
JSTwi
2010年11月10日水曜日
Microsoftの Webページ埋め込み用画像拡大ビューワーサービス Zoom.it
Zoom.itはMicrosoftのLive Labsが作ったWebページに埋め込める画像Viewer。
もともとはSeadragonという名前だったようだ。(参考:巨大な画像のビューアーを作ってくれる『Seadragon』 - 100SHIKI)
画像のURLを指定すると、その画像をZoom.it側で取り込んで、表示できるようになる。
Zoom.it側で取り込むので、見るときはZoom.itの発行するURLで見るか、埋め込み用のJavaScriptを自分のサイトに埋め込んで見る。
画像のファイルサイズは無制限のようだ。(参考:Zoom.it - FAQ)
Web公開用画像の外部ストレージサービスとしても使えるのかな...!
そしてこれ、画像だけでなく、実はWebページのキャプチャもしてくれる。URLとして、画像のURLの代わりにWebページのURLを入力するだけ。
UTF-8のページなら日本語でも問題なくキャプチャできた。(Shift_JISの場合は文字化けした。)
注意点としては、一度Zoom.itに取り込ませた画像は削除も変更もできない。「あなたがそのURLを公開しない限りは見つかることはないから大丈夫だよ」(Zoom.it - FAQ)と言われても、公開してしまったら後で困るかもしれないので慎重に?
これを作ったMicrosoftのLive LabsはBing部門に吸収された(参考:Microsoft Live Labs)ようだが、今後Zoom.itはどうしていくつもりなんだろう?
FlickrのようなCGMとして展開していかないのかな。
ところでZoom.itはGoogle Analyticsが仕込んである。MSも自前でアクセス統計を持ってなかったっけ?
もともとはSeadragonという名前だったようだ。(参考:巨大な画像のビューアーを作ってくれる『Seadragon』 - 100SHIKI)
画像のURLを指定すると、その画像をZoom.it側で取り込んで、表示できるようになる。
Zoom.it側で取り込むので、見るときはZoom.itの発行するURLで見るか、埋め込み用のJavaScriptを自分のサイトに埋め込んで見る。
画像のファイルサイズは無制限のようだ。(参考:Zoom.it - FAQ)
Web公開用画像の外部ストレージサービスとしても使えるのかな...!
そしてこれ、画像だけでなく、実はWebページのキャプチャもしてくれる。URLとして、画像のURLの代わりにWebページのURLを入力するだけ。
UTF-8のページなら日本語でも問題なくキャプチャできた。(Shift_JISの場合は文字化けした。)
注意点としては、一度Zoom.itに取り込ませた画像は削除も変更もできない。「あなたがそのURLを公開しない限りは見つかることはないから大丈夫だよ」(Zoom.it - FAQ)と言われても、公開してしまったら後で困るかもしれないので慎重に?
これを作ったMicrosoftのLive LabsはBing部門に吸収された(参考:Microsoft Live Labs)ようだが、今後Zoom.itはどうしていくつもりなんだろう?
FlickrのようなCGMとして展開していかないのかな。
ところでZoom.itはGoogle Analyticsが仕込んである。MSも自前でアクセス統計を持ってなかったっけ?
2010年11月9日火曜日
あなたの知らないbit.lyの便利機能
URL短縮サービス最大手のbit.ly。Yahooなど大手サイトの短縮も請け負ってもはやURL短縮サービスの代名詞になりつつある。
そんなbit.lyだが、URL短縮以外のサービスもやっていることについては意外と知らないのではないだろうか?
1. 後ろにプラスでクリック数やTwitterでのつぶやきを表示
短縮URLの後ろに"+"(プラス)を付けると、その短縮URLのアクセス統計が見られるのは有名。
でもTwitterでのつぶやき(最大99件)等も見られるようになっているのは知らなかった。
Twitterのつぶやきには、bit.lyで短縮されたものだけでなく、goo.glやTinyURLで短縮されたリンクも含まれて表示されている。BackTweetsから引っ張ってきているようだ。
URLがトップレベル等の場合、その配下の短縮URLも含めたTweetが表示される。(BackTweetsを使うからそうなるんだろう。)
下記の例は「はてなブックマーク」のトップページの短縮URLの統計ページだが、はてなブックマークのトップページだけだなく、はてなブックマーク内の全ての短縮URLのTweetが表示対象となっている。
例: bit.ly statistics for (はてなブックマーク)
また、クリック数はj.mpと共有しているようだ。→ http://j.mp/DeWI+
ちなみに、amzn.toなどのbit.lyの専用短縮URLの場合、プラスを付けるとbit.lyのページにリダイレクトされて統計が見られる。
例: http://amzn.to/CB7N+
2. QRコード
goo.glでは短縮URLの後ろに".qr"を付けるとQRコードが表示されるが、bit.lyもいつの間にか(?)実装していた。
bit.lyの場合、短縮URLの後ろに".qrcode"を付けるとQRコードが表示される。
例: http://j.mp/DeWI.qrcode
goo.glのQRコードより大きい。(goo.glには負けないという意気込みを感じる?)
QRコードは(株)デンソーウェーブの登録商標です。
3. 人気の動画を一覧表示
統計から人気の動画を選び、一覧表示しているようだ。 → bitly.tv | What the world is watching now
4. a.ly
http://a.ly にアクセスするとbit.lyにリダイレクトされる。
しかし残念ながら(?)このa.lyは短縮URLには使えないようだ。
そんなbit.lyだが、URL短縮以外のサービスもやっていることについては意外と知らないのではないだろうか?
1. 後ろにプラスでクリック数やTwitterでのつぶやきを表示
短縮URLの後ろに"+"(プラス)を付けると、その短縮URLのアクセス統計が見られるのは有名。
でもTwitterでのつぶやき(最大99件)等も見られるようになっているのは知らなかった。
Twitterのつぶやきには、bit.lyで短縮されたものだけでなく、goo.glやTinyURLで短縮されたリンクも含まれて表示されている。BackTweetsから引っ張ってきているようだ。
URLがトップレベル等の場合、その配下の短縮URLも含めたTweetが表示される。(BackTweetsを使うからそうなるんだろう。)
下記の例は「はてなブックマーク」のトップページの短縮URLの統計ページだが、はてなブックマークのトップページだけだなく、はてなブックマーク内の全ての短縮URLのTweetが表示対象となっている。
例: bit.ly statistics for (はてなブックマーク)
また、クリック数はj.mpと共有しているようだ。→ http://j.mp/DeWI+
ちなみに、amzn.toなどのbit.lyの専用短縮URLの場合、プラスを付けるとbit.lyのページにリダイレクトされて統計が見られる。
例: http://amzn.to/CB7N+
2. QRコード
goo.glでは短縮URLの後ろに".qr"を付けるとQRコードが表示されるが、bit.lyもいつの間にか(?)実装していた。
bit.lyの場合、短縮URLの後ろに".qrcode"を付けるとQRコードが表示される。
例: http://j.mp/DeWI.qrcode
goo.glのQRコードより大きい。(goo.glには負けないという意気込みを感じる?)
QRコードは(株)デンソーウェーブの登録商標です。
3. 人気の動画を一覧表示
統計から人気の動画を選び、一覧表示しているようだ。 → bitly.tv | What the world is watching now
4. a.ly
http://a.ly にアクセスするとbit.lyにリダイレクトされる。
しかし残念ながら(?)このa.lyは短縮URLには使えないようだ。
mod_pagespeedとは
Google製のApacheモジュール。インストールするだけでWebサイトを高速化できる。
Apache2.2向けに、CentOS用とUbuntu用が用意されている → Page Speed Downloads
以下は参考ページのリンク。
概要
Google、Apache モジュール「mod_pagespeed」をリリース - スラッシュドット・ジャパン
mod_pagespeed所感 - 最高のコンピューティング環境とは?
具体的な使用例
mod_pagespeed をちょっとだけ試してみた - 酒日記 はてな支店
mod_pagespeedをEC-CUBEを使って早速試してみる - なげっぱなし日誌
紀子さん@へぼぷろぐらまの日常 mod_pagespeedいれてみた。
mod_pagespeedを入れてみた - でぶろぐ
詳しい解説
続・mod_pagespeedの各Filterと設定について ハブろぐ - havelog.ayumusato.com
mod_pagespeedについての考察とか | Yet Another Geek Blog(日々の葛藤日記 Ver.2)
インストール
さくらのVPSにGoogleのmod_pagespeed入れてみた ハブろぐ - havelog.ayumusato.com
感想
けっこうドラスティックに変えちゃうみたい。
JavaScriptはMinifyするらしいけど、IE用の条件付きコンパイルは残してくれるのかな?
「Elide Attributes」がHTML5には対応してるかは要確認。
既存のサイトへのいきなりの適用は危険そう。新しいサイトなら開発段階からこれを使って作ってくのはありかも。
WordPressやRailsなどの代表的なCMSやFrameworkで「使えた」という報告が上がってくれば普及するかも?
Google App Engineでも同じようなことやればいいのに?(オプションとして提供するとか。)
Apache2.2向けに、CentOS用とUbuntu用が用意されている → Page Speed Downloads
以下は参考ページのリンク。
概要
Google、Apache モジュール「mod_pagespeed」をリリース - スラッシュドット・ジャパン
mod_pagespeed所感 - 最高のコンピューティング環境とは?
具体的な使用例
mod_pagespeed をちょっとだけ試してみた - 酒日記 はてな支店
mod_pagespeedをEC-CUBEを使って早速試してみる - なげっぱなし日誌
紀子さん@へぼぷろぐらまの日常 mod_pagespeedいれてみた。
mod_pagespeedを入れてみた - でぶろぐ
詳しい解説
続・mod_pagespeedの各Filterと設定について ハブろぐ - havelog.ayumusato.com
mod_pagespeedについての考察とか | Yet Another Geek Blog(日々の葛藤日記 Ver.2)
インストール
さくらのVPSにGoogleのmod_pagespeed入れてみた ハブろぐ - havelog.ayumusato.com
感想
けっこうドラスティックに変えちゃうみたい。
JavaScriptはMinifyするらしいけど、IE用の条件付きコンパイルは残してくれるのかな?
「Elide Attributes」がHTML5には対応してるかは要確認。
既存のサイトへのいきなりの適用は危険そう。新しいサイトなら開発段階からこれを使って作ってくのはありかも。
WordPressやRailsなどの代表的なCMSやFrameworkで「使えた」という報告が上がってくれば普及するかも?
Google App Engineでも同じようなことやればいいのに?(オプションとして提供するとか。)