AMPのキャッシュを更新するには、以前はupdate-pingが使用されていましたが廃止(deprecated)になりました。
2018年8月現在では、秘密鍵で署名したupdate-cacheリクエストを送る必要があります。
公式ドキュメントに従って、公開鍵の作成から、リクエストURLの作成方法までを紹介します。
公式ドキュメント
詳細は、次のページにかかれています。
AMP on Google > Google AMP Cache > Update Cache
https://developers.google.com/amp/cache/update-cache
リクエストURL作成方法
今回は、公式ドキュメント(“最終更新日: 7月 3, 2018” 版)に従って、update-cacheを行いました。
RSAキーの準備
ターミナルで次のようにして、公開鍵&秘密鍵のペアを作成します。
openssl genrsa 2048 > private-key.pem openssl rsa -in private-key.pem -pubout >public-key.pem
- opensslコマンドがインストールされていない場合はインストールしてください。
次に、作成したpublic-key.pemを、自分のAMPサイト(ここでは example.com)の次の場所にアップロードします。
https://example.com/.well-known/amphtml/apikey.pub
- public-key.pemは、apikey.pubとリネームします。
- .well-knownとamphtmlフォルダは作成します。
- httpsでないといけません。
- サブドメインのampサイトを対象にする場合は、apikey.pubを置く場所もサブドメインでなくてはいけません。
- text/plainで配信される必要があります。
apikey.pubのcontent-typeがtext/plainとなるように、.htaccessに次を追加します。
AddType text/plain .pub
- pubの前のドットは合ってもなくてもよいです。
curl などを使って、content-typeを確かめます。
$ curl -I https://example.com/.well-known/amphtml/apikey.pub HTTP/2 200 server: nginx date: Tue, 28 Aug 2018 14:01:42 GMT content-type: text/plain content-length: 451 last-modified: Tue, 28 Aug 2018 13:27:51 GMT etag: "1c3-5747ecf024d9e" accept-ranges: bytes
- content-typeが指定されていない状態でリクエストを送ったら、public key error (403)が出て失敗しましたので、指定しましょう。
RSAキーの設定は以上です。
リクエストURLの作成
リクエスト先のCDNサーバーは現状では、cdn.ampproject.orgのみのようです。
CDNサーバーに対し、次のようなリクエストを送ると、キャッシュの更新が行われることになります。
https://<example-com>.cdn.ampproject.org/update-cache/c/s/<example.com/article>?amp_action=flush&_ts=<ts_val>&_url_signature=<sig_val>
このURLを作成するのに必要なパラメーターは、次のとおりです。
<example-com>: ドメインをAMP Cache URL Formatでエンコードしたもの。単純には、”-“を”–“に、”.”を”-“に置き換えたものです。
<example.com/article>: キャッシュを更新したいURL
<ts_val>: unix time。リクエストを送る時間のプラマイ1分以内でないといけません。
<sig_val>: RSA暗号鍵で作成したキー。
<sig_val>の詳細
/update-cacheから<ts_val>までの部分をsha256で暗号化してから、web safeなbase64でエンコードします。
/update-cache/c/s/<example.com/article>?amp_action=flush&_ts=<ts_val>
実装
phpで実装を行うと次のようになります。stack overflowを参考に(というかほぼパクリ)しました。
function generateURL( $page ) {
$domain = 'example.com';
$url = $domain . $page;
$timestamp = time();
$ampBaseUrl = "https://" . str_replace( array( '-', '.' ), array('--', '-' ), $domain ) . ".cdn.ampproject.org";
$signatureUrl = '/update-cache/c/s/' . $url . '?amp_action=flush&_ts=' . $timestamp;
// opening the private key
$pkeyid = openssl_pkey_get_private( "file:///Users/boofoo/private-key.pem" );
if ( $pkeyid == false ) {
echo 'could not open the private key.';
exit;
}
// generating the signature
openssl_sign( $signatureUrl, $signature, $pkeyid, OPENSSL_ALGO_SHA256 );
openssl_free_key( $pkeyid );
// urlsafe base64 encoding
$signature = $this->urlsafe_b64encode( $signature );
// final url for updating
$ampUrl = $ampBaseUrl . $signatureUrl . "&_url_signature=" . $signature;
return $ampUrl;
}
function urlsafe_b64encode( $string ) {
return str_replace( array( '+', '/', '=' ), array( '-', '_', '' ), base64_encode( $string ) );
}
- generateURL関数にページのパス ( /example_page.htmlなど) を渡すと、リクエストURLが返ります。
- 関数内の$domainは先に指定しておきます。
- $domainには他バイト文字は入っていないと仮定しています。
あとは生成したURLに対して @file_get_contents( $url ); をすれば良いでしょう。
今回は多数のリクエストを送りましたが、1本のHTTPアクセスで、処理速度は 1分あたり300件でした。
1万ページくらいありますと30分以上かかることになります。
まとめ
update-pingは簡単でしたが、誰でもキャッシュ更新を行えるというセキュリティ上の問題がありました。
公開鍵を使用したupdate-cacheでは公開鍵をサイトにアップロードできるサイト管理者のみキャッシュ更新を行うことができます。
面倒ですが、一度コードを作成すれば済みますので、やってみてくださいね。
以上、AMPのCDNキャッシュをupdate-cacheを使って強制更新する方法。でした。
わかりやすい記事をありがとうごいざいます!
おかげさまで、無事にAMPキャッシュを更新することができました。
1点気づいたのですがRSAキーの準備のところで、「次に、作成したprivate-key.pemを、自分のAMPサイト(ここでは example.com)の次の場所にアップロードします。」とありますが、これは公開鍵の public-key.pem ではないでしょうか?
おっしゃる通り、記事の方が間違っていてアップロードするのは公開鍵のpublic-key.pemでした。秘密鍵を公開してはいけませんね、、。記事を修正いたしました。親切にご指摘いただきましてありがとうございました。