コンテンツにスキップ

サイトの認証

Craft Sitesでは サイトの認証 を有効化することで、署名付きURLおよび署名付きCookieによるサイトの認証が実現できます。

サイトの認証を有効化する

サイトの認証はサイトの作成時および作成後に有効化できます。

KARTE管理画面の「すべてのメニュー」>「Craft」>「サイト」で表示されるサイト一覧画面から設定できます。

サイトの作成時に有効化する

  • 「作成」を選択して現れるメニューで サイトの認証を有効にする をチェックします
  • 他の必須項目を指定してから「保存」を選択してください。

サイトの作成後に有効化する

  • 対象サイト欄の「…」から「設定」を選択し、現れたメニューで サイトの認証を有効にする をチェックして「保存」を選択してください。

サイトの認証の仕組み

ユーザーがサイトの認証を有効にすると、Craft Sitesはサイトの設定を次のように変更します。

  • 署名用の鍵を発行します。この鍵を使って署名付きURL/署名付きCookieを発行します。
    • 署名用の鍵の値を、 Craft Secret ManagerCSP_{{サイト名(大文字)}} という名前のシークレットに登録します。
  • サイトを限定公開の状態にします。
    • 署名付きURL/署名付きCookie による認証がある場合のみ、サイトへのアクセスが可能になります。

署名用の鍵はCraft Secret Managerに格納されるため、署名付きURL/Cookieを発行するためにはCraft Functions経由で鍵の値を取得する必要があります。

署名付きURLを発行する

署名付きURLの発行にはCraft Functionsを利用します。サンプルコードは次のとおりです。

Functionの変数には次の値を設定します。

 変数名 値の例 説明
AUTH_KEY_SECRET_NAMECSP_SITE_NAME署名鍵のシークレット名です。Craft Secret Managerのシークレット一覧にある CSP_{{サイト名(大文字)}} という名前を指定してください。
AUTH_KEY_NAMEcsp-key署名生成時に必要な鍵名です。 csp-key の固定値です。
LOG_LEVELDEBUGログレベルです。 DEBUG,INFO,WARN,ERRORのいずれかを指定してください。
import crypto from "crypto";
const AUTH_KEY_SECRET_NAME = "<% AUTH_KEY_SECRET_NAME %>";
const AUTH_KEY_NAME = "<% AUTH_KEY_NAME %>";
const LOG_LEVEL = "<% LOG_LEVEL %>";
function signUrlPrefix(urlPrefix, keyName, base64Key, expirationTimeUnix) {
const decodedKey = Buffer.from(base64Key, "base64");
const encodedUrlPrefix = Buffer.from(urlPrefix)
.toString("base64")
.replace(/\+/g, "-")
.replace(/\//g, "_");
const policy = `URLPrefix=${encodedUrlPrefix}&Expires=${expirationTimeUnix}&KeyName=${keyName}`;
const hmac = crypto.createHmac("sha1", decodedKey);
hmac.update(policy);
const signature = hmac
.digest("base64")
.replace(/\+/g, "-")
.replace(/\//g, "_");
return `${urlPrefix}?${policy}&Signature=${signature}`;
}
export default async function (data, { MODULES }) {
const { initLogger, secret } = MODULES;
const logger = initLogger({ logLevel: LOG_LEVEL });
logger.debug(AUTH_KEY_NAME, AUTH_KEY_SECRET_NAME, LOG_LEVEL);
const { req, res } = data;
// 署名鍵の値を取得する
const { [AUTH_KEY_SECRET_NAME]: base64Key } = await secret.get({
keys: [AUTH_KEY_SECRET_NAME],
});
if(!base64Key) return res.status(500).send("Auth key is null or undefined.");
const { urlPrefix, expiredSeconds } = req.body;
if (!urlPrefix) return res.status(400).send("urlPrefix is required.");
const expirationTimeUnix = Math.floor(Date.now() / 1000) + expiredSeconds;
const signedUrl = signUrlPrefix(
urlPrefix,
AUTH_KEY_NAME,
base64Key,
expirationTimeUnix
);
return res.json({ signedUrl });
}

Craft Endpointを作成して、Endpoint経由でファンクションを起動します。以下はCurlで起動する場合のコマンド例です。

Terminal window
curl -X POST '{{エンドポイントのURL}}' \
-H 'Content-Type: application/json; charset=UTF-8' \
-d '{"urlPrefix": "{{署名対象のURL}}", "expiredSeconds": 600 }'

署名付きCookieを発行する

署名付きCookieの発行も同様にCraft Functionsから行います。

サンプルコードは次のとおりです。Functionの変数には次の値を設定します。

変数名値の例説明
AUTH_KEY_SECRET_NAMECSP_SITE_NAME署名鍵のシークレット名です。Craft Secret Managerのシークレット一覧にある CSP_{{サイト名(大文字)}} という名前を指定してください。
AUTH_KEY_NAMEcsp-key署名生成時に必要な鍵名です。 csp-key の固定値です。
LOG_LEVELDEBUGログレベルです。 DEBUG,INFO,WARN,ERROR,NONEのいずれかを指定してください。
import crypto from "crypto";
const AUTH_KEY_SECRET_NAME = "<% AUTH_KEY_SECRET_NAME %>";
const AUTH_KEY_NAME = "<% AUTH_KEY_NAME %>";
const LOG_LEVEL = "<% LOG_LEVEL %>";
function generateSignedCookie(
urlPrefix,
keyName,
base64Key,
expirationTimeUnix
) {
const decodedKey = Buffer.from(base64Key, "base64");
const encodedUrlPrefix = Buffer.from(urlPrefix)
.toString("base64")
.replace(/\+/g, "-")
.replace(/\//g, "_");
const input = `URLPrefix=${encodedUrlPrefix}:Expires=${expirationTimeUnix}:KeyName=${keyName}`;
const hmac = crypto.createHmac("sha1", decodedKey);
hmac.update(input);
const signature = hmac
.digest("base64")
.replace(/\+/g, "-")
.replace(/\//g, "_");
return `Cloud-CDN-Cookie=${input}:Signature=${signature}`;
}
export default async function (data, { MODULES }) {
const { initLogger, secret } = MODULES;
const logger = initLogger({ logLevel: LOG_LEVEL });
logger.debug(AUTH_KEY_NAME, AUTH_KEY_SECRET_NAME, LOG_LEVEL);
// 署名鍵の値を取得する
const { [AUTH_KEY_SECRET_NAME]: base64Key } = await secret.get({
keys: [AUTH_KEY_SECRET_NAME],
});
const { req, res } = data;
if(!base64Key) return res.status(500).send("Auth key is not found.");
const { urlPrefix, expiredSeconds } = req.body;
if (!urlPrefix) return res.status(400).send("urlPrefix is required.");
const expirationTimeUnix = Math.floor(Date.now() / 1000) + expiredSeconds;
const signedCookie = generateSignedCookie(
urlPrefix,
AUTH_KEY_NAME,
base64Key,
expirationTimeUnix
);
return res.json({ signedCookie });
}

Craft Endpointを作成して、Endpoint経由でファンクションを起動します。以下はCurlで起動する場合のコマンド例です。

Terminal window
curl -X POST '{{エンドポイントのURL}}' \
-H 'Content-Type: application/json; charset=UTF-8' \
-d '{"urlPrefix": "{{署名対象のURL}}", "expiredSeconds": 600 }'