エアRTは家庭崩壊を招きかねないので絶対にしちゃだめです。
こんばんは。
そろそろモバゲーも mixi さんに続いて Yahoo! と協力して PC版 OpenSocial アプリケーションプラットフォームをリリースするそうです。というかします。
で、OpenSocial JS API では、外部のサーバーと安全に通信するための仕組みとして、Gadget Server を Proxy してリクエストする gadgets.io.makeRequest() という、メソッドが用意されています。このメソッドはオプションでリクエストに署名をつけることができて、受け手でその署名を検証することによってリクエストの妥当性を保証することができます。
これを Perl で実装する場合、詳しくは mala さんの mixiアプリのOAuth署名の検証 の記事が詳しいのですが、もうちょっと突っ込んで説明して PSGI/Plack で実装してみます。
例えばアプリケーションでGadget XMLで
function init() {
var params = {};
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
params[gadgets.io.RequestParameters.POST_DATA] = gadgets.io.encodeValues({id:123456789});
params[gadgets.io.RequestParameters.REFRESH_INTERVAL] = 0;
gadgets.io.makeRequest("http://example.com/", function(obj) {
console.dir(obj);
var user = obj.data;
alert(user.name + " loves AKB48.");
}, params);
}
ようなことをします。
肝は
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
で、これにより Gadget Server からのリクエストに OAuth の署名がつくので、それを検証することによってリクエストの妥当性が保証できます。
受ける方のアプリケーションを PSGI/Plack で実装します。
use OAuth::Lite::ServerUtil;
use Crypt::OpenSSL::CA;
use JSON;
my $cert = <<__PUBLIC_KEY__;
-----BEGIN CERTIFICATE-----
MIICdzCCAeCgAwIBAgIJANCWpLIspxwbMA0GCSqGSIb3DQEBBQUAMDIxCzAJBgNV
BAYTAkpQMREwDwYDVQQKEwhtaXhpIEluYzEQMA4GA1UEAxMHbWl4aS5qcDAeFw0x
MDAzMjMwODE1NTlaFw0xMjAzMjIwODE1NTlaMDIxCzAJBgNVBAYTAkpQMREwDwYD
VQQKEwhtaXhpIEluYzEQMA4GA1UEAxMHbWl4aS5qcDCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEAtbq5Rns5IEktXldZ+37Fjlavnuc4JuwrD4F+4NQwVwVtR5yw
Vg10EanXWSGIAbUFx6hlppYOb0x/3PBMG80643LmXSJmvv4ViRUBl2Ys9Ie2L/D9
KVQXDWgJjxBGqo5MO6rA/Ip78kbiNbIQJUIJtbuJZWL3LMVe6mpIO2SUi1UCAwEA
AaOBlDCBkTAdBgNVHQ4EFgQU8bp8/6lmt5L8em6dZyoGciUUmuUwYgYDVR0jBFsw
WYAU8bp8/6lmt5L8em6dZyoGciUUmuWhNqQ0MDIxCzAJBgNVBAYTAkpQMREwDwYD
VQQKEwhtaXhpIEluYzEQMA4GA1UEAxMHbWl4aS5qcIIJANCWpLIspxwbMAwGA1Ud
EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEApalbBgXxnLJW8fM6W7E7GAE4QZbE
lvYqvtQSxwacGYoqF2FW1zrBkmTB12LTddFU01pqDaeels3Ru5TNOnTIJemFWW0D
viKtu9GqsrOye6AZR+XA5Iy/vq3EV1TCGuDNmhJaHAiLeYuLbEqmvH7/l9xNsafH
IpqnsHwF1pm0bTY=
-----END CERTIFICATE-----
__PUBLIC_KEY__
my $ca = Crypt::OpenSSL::CA::X509->parse($cert);
my $public_key = $ca->get_public_key->to_PEM;
my $app = sub {
my $req = Plack::Request->new(shift);
my $util = OAuth::Lite::ServerUtil->new;
$util->support_signature_method('RSA-SHA1');
my $res = $util->verify_signature(
method => $req->method,
url => $req->uri,
params => $req->parameters,
consumer_secret => $public_key,
);
my $body = encode_json({id => 12345, name => 'hidek'});
return $res
? [200, ['Content-Type' => 'application/json'], [$body]]
: [403, ['Cbntent-Type' => 'text/plain'], ['Forbidden']];
};
gadgets.io.makeRequest() のリクエストの OAuth 署名形式はその使い勝手から mixi さんもモバゲーも RSA-SHA1 で行っているので妥当性の検証は公開鍵を使って行います。検証は例によって lyokato さんの OAuth::Lite に頼るわけですが、 mala さんが指摘している通り、mixi で公開されている公開鍵はX509なのでそのまま使えないため、変換する必要があります。
後はリクエストを OAuth::Lite::ServerUtil に食わせて署名のチェックを行って、それによりレスポンスを変えます。
例では mixi さんの公開鍵を使わせてもらいましたが、もちろん公開鍵を今後公開されるモバゲーのものにかえたらそのまま動きます。
まあ、本来この辺は Middleware に含めるほうが使いかってがいいですね。





