サイトの認証
Craft Sitesでは サイトの認証 を有効化することで、署名付きURLおよび署名付きCookieによるサイトの認証が実現できます。
サイトの認証を有効化する
サイトの認証はサイトの作成時および作成後に有効化できます。
KARTE管理画面の「すべてのメニュー」>「Craft」>「サイト」で表示されるサイト一覧画面から設定できます。
サイトの作成時に有効化する
- 「作成」を選択して現れるメニューで サイトの認証を有効にする をチェックします
- 他の必須項目を指定してから「保存」を選択してください。
サイトの作成後に有効化する
- 対象サイト欄の「…」から「設定」を選択し、現れたメニューで サイトの認証を有効にする をチェックして「保存」を選択してください。
サイトの認証の仕組み
ユーザーがサイトの認証を有効にすると、Craft Sitesはサイトの設定を次のように変更します。
- 署名用の鍵を発行します。この鍵を使って署名付きURL/署名付きCookieを発行します。
- 署名用の鍵の値を、 Craft Secret Managerの
CSP_{{サイト名(大文字)}}
という名前のシークレットに登録します。
- 署名用の鍵の値を、 Craft Secret Managerの
- サイトを限定公開の状態にします。
- 署名付きURL/署名付きCookie による認証がある場合のみ、サイトへのアクセスが可能になります。
署名用の鍵はCraft Secret Managerに格納されるため、署名付きURL/Cookieを発行するためにはCraft Functions経由で鍵の値を取得する必要があります。
署名付きURLを発行する
署名付きURLの発行にはCraft Functionsを利用します。サンプルコードは次のとおりです。
Functionの変数には次の値を設定します。
変数名 | 値の例 | 説明 |
---|---|---|
AUTH_KEY_SECRET_NAME | CSP_SITE_NAME | 署名鍵のシークレット名です。Craft Secret Managerのシークレット一覧にある CSP_{{サイト名(大文字)}} という名前を指定してください。 |
AUTH_KEY_NAME | csp-key | 署名生成時に必要な鍵名です。 csp-key の固定値です。 |
LOG_LEVEL | DEBUG | ログレベルです。 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で起動する場合のコマンド例です。
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_NAME | CSP_SITE_NAME | 署名鍵のシークレット名です。Craft Secret Managerのシークレット一覧にある CSP_{{サイト名(大文字)}} という名前を指定してください。 |
AUTH_KEY_NAME | csp-key | 署名生成時に必要な鍵名です。 csp-key の固定値です。 |
LOG_LEVEL | DEBUG | ログレベルです。 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で起動する場合のコマンド例です。
curl -X POST '{{エンドポイントのURL}}' \ -H 'Content-Type: application/json; charset=UTF-8' \ -d '{"urlPrefix": "{{署名対象のURL}}", "expiredSeconds": 600 }'