LoginSignup
1
2

Github PagesでGASを使ってキーワード認証を行う

Last updated at Posted at 2024-03-03

はじめに

Github Pages で公開したサイトでキーワード認証をしたい.
しかし,静的サイトなのでサーバー側で認証を行うことができません.また,キーワード認証を Github Pages だけで行おうとすると(javascript で行おうとすると)コードを見られたときに,キーワードがばれてしまいます.
そのため,無料で使える GAS(Google Apps Script)を使ってキーワード認証を行う方法を紹介します.

part1 はこちら
こちらで GAS を使ってデータを保存・取得する方法を紹介しています.

今回の目標

image.png

データの保存・取得は part1 で紹介したので,今回は GAS でキーワード認証を行います.

イメージは,以下のようになります.

  1. キーワードそのキーワードが送信されたときのレスポンスを登録する
    1. POST リクエストでキーワードレスポンスを登録する
    2. 例えば,キーワード : password, レスポンス : 認証成功
    3. データベース(spreadsheet)に登録される
  2. GithubPages でできたサイトでキーワードを送信する
    1. GET リクエストでキーワードを送信する
    2. データベース(spreadsheet)に登録されているキーワードと一致するかを確認する
    3. 一致したら,登録されているレスポンスを返す
  3. GithubPages でできたサイトでレスポンスを確認できる

簡単に言うと,ログイン画面のようなものです.パスワードを入力すると,認証が通るかどうかを確認できます.ただし,画面遷移は行いません.

GAS コードの作成

前回からの変更点は,GET と POST リクエストの方法です.

  • GET リクエスト

    • クエリパラメータを使って,キーワードを渡します.
    • キーワードが一致したら,認証突破後のデータを返します.
  • POST リクエスト

    • リクエストボディを使って,キーワードと情報を渡します.
    • キーワードと情報をペアで登録します.
  • スプレッドシート

    • 今回は A 列にキーワード,B 列に情報を登録します.
    • 同じ行のものがペアになります.
    • 新しいものは最終行に追加されます.

プロジェクトによってシート名を変更できるようにするため,シート名は指定できるようにしますが,複数キーワードがある場合を考えて,セル名は指定しません.

リクエストデータ

GET

https://script.google.com/macros/s/GASのデプロイID/exec?sheetName=シート名&keyword=キーワード

クエリパラメータ部分は?sheetName=シート名&keyword=キーワードです

POST

{
  "sheet": "シート名",
  "keyword": "値",
  "resp": "レスポンス"
}

前回同様,データをエンコードしたほうがいいかもしれませんが,今回は省略します.
そのため,日本語でデータをkeywordを送ると,文字化けするかもしれません.
その場合は,エンコードするか,英語などで送るようにしてください.

GAS コード

長くなるので POST と GET を分けて書きます.

POST

// スプレッドシートの最終行(空白の行)を取得
function findEmptyRow() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var columnA = sheet.getRange("A:A").getValues();

  var row = 0;
  for (var i = 0; i < columnA.length; i++) {
    if (columnA[i][0] == "") {
      row = i + 1;
      break;
    }
  }

  return row;
}

function doPost(e) {
  const string = e.postData.getDataAsString();
  const JsonData = JSON.parse(string);
  const sheetName = JsonData.sheet;
  const keyword = JsonData.keyword;
  const resp = JsonData.resp;

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(sheetName);
  let row = findEmptyRow();
  sheet.getRange("A" + row).setValue(keyword);
  sheet.getRange("B" + row).setValue(resp);
  var data = { valid: true };

  const response = ContentService.createTextOutput();
  response.setMimeType(ContentService.MimeType.JSON);
  response.setContent(JSON.stringify(data));

  return response;
}

このコードでは,最終行にキーワードとレスポンスを登録します.

GET

// vlookup関数
function vlookup(searchKey, range, index, isSorted) {
  for (var i = 0; i < range.length; i++) {
    if (range[i][0] === searchKey) {
      return range[i][index - 1];
    }
  }

  if (isSorted) {
    return "#N/A";
  }

  return null;
}

function doGet(e) {
  const sheetName = e.parameter.sheetName;
  const cell = e.parameter.cell;

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(sheetName);
  var range = sheet.getRange("A:B").getValues();
  var result = vlookup("searchKey", range, 2, false);

  var data = { valid: true, value: result };
  if (result === null) {
    data = { valid: false, value: "not found" };
  }

  const response = ContentService.createTextOutput();
  response.setMimeType(ContentService.MimeType.JSON);
  response.setContent(JSON.stringify(data));

  return response;
}

このコードでは,キーワードを A 列から探し,一致したら同じ行の B 列のデータを返します.

Github Pages で使う

最後に,Github Pages で使うために,fetch を使ってデータを送受信します.

fetch の使い方

async function fetchData(url, options) {
  try {
    const response = await fetch(url, options);
    const data = await response.json();
  } catch (error) {
    console.error("Error:", error);
  }
}

GET

// GASのurlにクエリパラメータ(?sheetName=シート名&cell=セル名)を付ける
const url =
  "https://script.google.com/macros/s/GASのデプロイID/exec?sheetName=シート名&keyword=キーワード";
const options = {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
  },
};
fetchData(url, options);

POST

// GASのurl
const url = "https://script.google.com/macros/s/GASのデプロイID/exec";
const options = {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    sheet: "シート名",
    keyword: "",
    resp: "レスポンス",
  }),
};
fetchData(url, options);

まとめ

GAS を使って,Github Pages サイトでキーワード認証を行う方法を紹介しました.
これで,ログイン画面も作れる!ということになりますが,画面遷移を行うと,次はその url にアクセスをすれば良くなってしまうので,注意が必要です.
また,Github の有料プランに入っていないと,コードが完全に公開されてしまうので,このサイトにどのようなパスがあるかが全て分かってしまいます.

image.png

次回

それでは,GithubPages でログイン画面を作るにはどうしたらよいのかを考えていきます.

1
2
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
1
2