我正在尝试使用此文档实现 Google AMP 更新缓存请求。
我的实现
按照教程中的建议,首先我从https://cdn.ampproject.org/caches.json获取缓存信息,然后遍历这些缓存以执行更新。
单个缓存的简化代码(因为目前只有一个):
主要逻辑
String firstPartUrl = "https://amp--frontend-dpo-styria--publishing-com.cdn.ampproject.org"
String secondPartUrl = "/update-cache/c/s/amp-frontend.dpo.styria-publishing.com/octopus/5267614?amp_action=flush&_ts=1505218616"
secondPartUrl = signRequestUrl(secondPartUrl);
performRequest(firstPartUrl, secondPartUrl);
签名功能
private String signRequestUrl(String requestUrl) throws Exception {
URL url = Resources.getResource("rsa/private-key-pcks8.pem");
String privateKey = Resources.toString(url, Charsets.UTF_8);
String signature = signSHA256RSA(requestUrl, privateKey);
StringBuilder builder = new StringBuilder(requestUrl);
builder.append("&_url_signature=");
builder.append(signature);
return builder.toString();
}
public static String signSHA256RSA(String input, String privateKey) throws Exception {
// Remove markers and new line characters in private key
String realPK = privateKey.replaceAll("-----END PRIVATE KEY-----", "")
.replaceAll("-----BEGIN PRIVATE KEY-----", "")
.replaceAll("\r\n", "")//windows
.replaceAll("\n", "");//unix
byte[] b1 = Base64.getDecoder().decode(realPK);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(b1);
KeyFactory kf = KeyFactory.getInstance("RSA");
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(kf.generatePrivate(spec));
privateSignature.update(input.getBytes());
byte[] s = privateSignature.sign();
return Base64.getUrlEncoder().withoutPadding().encodeToString(s);
}
我的公钥在这里发布:https ://amp-frontend.dpo.styria-publishing.com/.well-known/amphtml/apikey.pub
我试过的
我什至尝试按照命令行中的签名步骤进行操作,但即使在此之后,我获得的 URL 仍返回 403。
我尝试遵循这个问题的提示(确保我使用 SHA256 并将 apikey 的内容类型设置为 text/plain,但它没有帮助)
我的问题
你知道为什么 Google AMP 仍然返回 403 吗?我怀疑我的 Base64 编码可能存在问题,因为文档对此不是很清楚,但我不确定。
编辑
我意识到函数构建的实现可能存在问题secondPartUrl
- 特别是时间戳。我使用创建了时间戳ZonedDateTime.now()
,这显然是错误的,因为我在与 UTC 不同的时区。但是,将其更改为Instant.now()
没有帮助。