質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

GASとGSSを使ったパスワード照合が必ず不一致になる

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 619

yukitorte

score 9

お世話になります。
GASで出力したhtml(webアプリケーション)でパスワード制限をかけようとしているのですが、
スプレッドシート(GSS)のデータとの照合がうまくいっていないようなので
お知恵をお貸しいただけますでしょうか。

やりたいこと

・indexにてパスワードを入力し送信
・GSS内のパスワードリストを照会し、正しければMenu1.htmlを、正しくなければMenu2.htmlを表示する
・GSS内のログシートへ、入場日時と照会の結果と使用パスワードを記録する

状況

・パスワードリストに含まれている文字列を入力しても必ずMenu2へ遷移する
・特定のパスワードのみ有効な形式にしたときはMenu1に遷移できる(後述)

現在のコード

function doGet(e){
  var page=e.parameter["p"];

  if(page == "index" || page==null){
  return HtmlService.createHtmlOutputFromFile('Index'); //入口
  } else if(page =="menu1"){
    return HtmlService.createHtmlOutputFromFile('Menu1'); //パスワード一致時に表示するページ
  } else if(page =="menu2"){
    return HtmlService.createHtmlOutputFromFile('Menu2'); //パスワード不一致時に表示するページ
  } else{
    return HtmlService.createHtmlOutputFromFile('Error'); //不正なURLを直打ちした時のページ
  }
}


function doPost(e){
  Logger.log(e);
  var SS = SpreadsheetApp.openById('***************************');//参照先のSSのID
  var passSh = SS.getSheetByName('pass') //パスワード格納シート
  var passVal = passSh.getDataRange().getValues(); //passシート内の値を取得
  var LastRow = passSh.getDataRange().getLastRow(); //passシート内の最終行
  var col = "B"; //passリストが記載されている列

  var LogSh = SS.getSheetByName('test_log') //ログ記録シート
  var date = new Date();
  var today = Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd HH:mm"); //dateのフォーマット指定

  var pass = e.parameter.name; //入力された文字列の受取


  for(var row = 9; row <= LastRow-1; row++) { //rowを9行目から最終行まで値を1ずつ増加
    if(passVal[row][col] === pass){
      var array = [date,"Success",pass];
      LogSh.appendRow(array);   
      return HtmlService.createHtmlOutputFromFile('Menu1').setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);

      } else{
      var array = [date,"fail",pass];
      LogSh.appendRow(array);
      return HtmlService.createHtmlOutputFromFile('Menu2').setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
    }     
  }
}


※passShのパスワードが羅列されているリストは、
A  B  C
8 No PASS ユーザー名
9  1 hoge1 ユーザーA
10 2 hoge2 ユーザーB
といった感じで、以下400程度『No』『PASS』『ユーザー名』が続いています。
ユーザー名は入力式ではなく、使用されたパスワードと所持ユーザーを紐付けるためだけの目的です。

試した事

現状、ログシートには入力したとおり正常に記録されていて
文字化け等もないため、文字列は正常に受け取っているとは思います。
となると、if構文の中身に問題がある(照会の仕方が悪い)か、
passValが正しくデータを取得できていないか……のどちらかではないかと思っていますが……。

for構文を取り払って、if("hogehoge" === name)) { ......という形にして
indexのパスワードフォームで『hogehoge』を入力すると、想定どおりMenu1へ移動しました。


初歩的な内容で大変申し訳ありませんが、どうぞよろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

for構文を取り払って、if("hogehoge" === name)) { ......という形にして
indexのパスワードフォームで『hogehoge』を入力すると、想定どおりMenu1へ移動しました。

であれば、passVal[row][col]が意図通りシートの値を意図通りに取得できていないのでしょう。
ログに出力などして確認しましょう、


それはともかく、

var col = "B"; //passリストが記載されている列
// 省略
passVal[row][col]


はおかしいです。
passValは2次元配列(ジャグ配列)なので、colは数値を指定する必要があります。
2列目の値を得たいのであれば、var col = 2;でしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/04 13:30 編集

    draqさんご回答ありがとうございます!

    var col = 2;に修正した上で
    console.log('入力値:' + pass + ' 拾った値:' + passVal[row][col]) ;を仕込んで
    実行してみたところ、相変わらずMenu2(不一致)へ遷移したうえで
    コンソールログでは 入力値:hogehoge 拾った値: となりました。(拾った値が空欄でした)
    やはりpassVal[row][col]が値を取得できていない感じがしますね……。

    力足らずで申し訳ありません、
    よろしければ引き続きご助力よろしくお願いします!

    キャンセル

  • 2020/02/04 14:28

    ご助力をもとに自己解決いたしました!
    ログで確認、大事ですね……。
    またコード迷子になった際はどうぞよろしくお願いいたします。

    キャンセル

0

経緯の前に解決コードをぺたり……。

function doPost(e){
  Logger.log(e);
  var SS = SpreadsheetApp.openById('***************************');//参照先のSSのID
  var passSh = SS.getSheetByName('pass') //パスワード格納シート
  var passVal = passSh.getDataRange().getValues(); //passシート内の値を取得
  var LastRow = passSh.getDataRange().getLastRow(); //passシート内の最終行
  var col = 1; //passリストが記載されている列

  var LogSh = SS.getSheetByName('test_log') //ログ記録シート
  var date = new Date();
  var today = Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd HH:mm"); //dateのフォーマット指定

  var pass = e.parameter.name; //入力された文字列の受取


  for(var row = 8; row <= LastRow-1; row++) { //rowを9行目から最終行まで値を1ずつ増加
    if(passVal[row][col] === pass){
      var array = [date,"Success",pass];
      console.log('入力値:' + pass + ' 取得値:' + passVal[row][col]) ;
      LogSh.appendRow(array);   
      return HtmlService.createHtmlOutputFromFile('Menu1').setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
      }
    }
  if(row = LastRow) {
      console.log('パスワード不一致。入力値:' + pass );
      var array = [date,"fail",pass];
      LogSh.appendRow(array);
      return HtmlService.createHtmlOutputFromFile('Menu2').setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
  }
}

draqさんのご助言をいただいたあと、
返り値がundefinedでもなく空欄っておかしいな?とふと思い、
passシートを見直したところ10行目がまるっと空欄だったことに気づきました。
(hogehogeパスやユーザー名は11行目から記載されてました……)

空白で検索が躓いたのでは……と空欄を削除して実行したところ、
ログが入力値:hogehoge 拾った値:ほげほげユーザーと返されていたため、
2次元配列のB列は2ではなく1かも?と思い、var col = 1;に変更。
するとhogehogeパスでMenu1へ遷移することに成功しました。

が、10行目以外のパスを受け付けず、不一致扱いに。
11行目の別パスワードを入力すると入力値:hogehoge2 拾った値:hogehogeとなったため
どうやら10行目以降の検索ができていないのでは?と推測。

原因は、for構文の内部で『パスが一致したらMenu1、不一致ならMenu2』のif・elseをしていたため
リストforループをする前に『不一致ならMenu2』という結果をreturnして終了したのかなと。
なのでelseを撤廃し、forの後ろで『row=LastRow(最終行まで検索した)になったらMenu2へ』
という形にしたところ、想定どおりの動作となりました。

コードとしてスマートなのかはわかりませんが(笑)、
ひとまずの解決をみたため、こちらの質問は解決とさせていただきます。
お世話になりました!

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る