0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CloudFront Functionsで一つの関数に複数サイトのBASIC認証情報をまとめて設定する方法

Last updated at Posted at 2023-04-05

以下の内容を全文コピペして貼り付けると良いのだ
トリガーは 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の練習がてら作成。

constletbtoaBuffer.from が使えなくてアレって思った。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?