以下の内容を全文コピペして貼り付けると良いのだ
トリガーは ViewerRequest
にするのだ
getAuthMaps
関数内に、設定したいサイトのホスト名と、BASIC認証のID/PWを適宜入力するのだ
特定のディレクトリ配下にだけBASIC認証をかけたい?知らね
/**
* Get basic auth informations
*
* @return {Array-object} maps
*/
function getAuthMaps()
{
var maps = [
{ "hostname": "test.example.com", "username": "onamae", "password": "pasuwaado" },
{ "hostname": "test.example2.com", "username": "onamae2", "password": "pasuwaado2" }
];
return maps;
}
/**
* Get specified basic auth information by hostname
*
* @param {string} hostName
* @return {object|false} item
*/
function getAuthInfoByHostName(hostName)
{
var maps = getAuthMaps();
var key = "hostname";
var items = maps.filter(function(v){
return v[key] === hostName;
});
var item = items.length > 0 ? items[0] : false;
return item;
}
/**
* Get base64 encoded token by username and password
*
* @param {object|false} item
* @return {string} authorization e.g. "Basic b25hbWFlOnBhc3V3YWFkbw=="
*/
function createAuthToken(item)
{
if(! item) return false;
var userName = item.username;
var passWord = item.password;
var token = (userName + ":" + passWord).toString("base64");
var authorization = "Basic " + token;
return authorization;
}
/**
* Check user request is authenticated or not.
*
* @param {object} request [should be cloudfront request formatted]
* @return {boolean} isAuth
*/
function authorize(request)
{
var headers = request.headers;
var hostName = headers.host.value;
var item = getAuthInfoByHostName(hostName);
var authorization = createAuthToken(item);
var isAuth = authorization && headers.authorization && headers.authorization.value === authorization;
return isAuth;
}
/**
* It returns unauthorized error response.
*
* @return {object} response
*/
function showError401()
{
var response = {
statusCode: 401,
statusDescription: "Unauthorized",
headers: {
"www-authenticate": {value: "Basic"}
}
};
return response;
}
/**
* Perform directory completion
*
* @param {object} request [should be cloudfront request formatted]
* @return {void}
*/
function directoryIndex(request)
{
var uri = request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith('/')) {
request.uri += 'index.html';
}
// Check whether the URI is missing a file extension.
else if (!uri.includes('.')) {
request.uri += '/index.html';
}
}
/**
* Do main process
*/
function handler(event)
{
var request = event.request;
// BASIC Authorization
var isAuth = authorize(request);
if (! isAuth) return showError401();
// Directory Index
//directoryIndex(request);
return request;
}
CloudFrontはサブディレクトリのインデックス補完がないので、
/foo/bar/
にアクセスしても 403エラーになります。
/foo/bar/
にアクセスした時に /foo/bar/index.html
を読み込むようにインデックス補完がしたい場合、
handler
メソッド内にある directoryIndex
関数のコメントアウトを解除してください。
ネットに書いてある記事はひとつの関数に
ひとつのサイトのBASIC認証情報をハードコーディングしているものが多く、
同じ記述の関数を何個も量産するのもな~と思ったので、CloudFront Functionsの練習がてら作成。
const
や let
や btoa
や Buffer.from
が使えなくてアレって思った。