1
3

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 3 years have passed since last update.

JavascriptだけでWebサイトにreCAPTCHAを実装してみた話

Last updated at Posted at 2021-05-27

###[注意]この記事ではJavascriptでreCAPTCHAの認証を行なっています。
###この方法は少しでも知識がある人ならばreCAPTCHAを行わずにformを送信できてしまいます。
###phpなどのサーバーサイド言語が使用できないレンタルサーバーを使用しているなどの特別な事情がない限りはこの記事に従わず、サーバー上でreCAPTCHAの認証を行うようにしてください。

##どういう経緯でこれをやろうと思ったか
私が初めてコードでプログラミングしたのはjavascriptだったんです。
なぜならiPadのSafariだけで開発とテストができるから。
アプリを入れなくていいっていうのは結構魅力的だったんです。
色々無料のレンタルサーバーを調べて、FC2の無料レンタルサーバーを借りることにしました。
なんでそこにしたのかと言うと…
・Web上で全て完結させられること。
・無料だったこと。
・なんか目についたから。
当時はレンタルサーバーなんてどこがいいか知らなかったしサーバーサイド言語とクライアントサイド言語の違いすら知らなかったんです。
そこで適当に見栄えのクソ悪い適当にボタンとリンク並べただけのページを作ったりして遊んでいたんです。
しばらく経って「なんかよく見る『私はロボットではありません』って言うボタンなんかかっこいいからつけてみたい!」と思ってネットで検索してコードを見つけたのでコピペしたら…
「ギャー!😱」phpのコードがまるまるhtmlに出力されちゃってました。
原因を調べると…
なんとfc2無料レンタルサーバーは__phpなどのサーバーサイド言語が使用不可だったんです。__
「そんなのアカウント作る前に調べておけよ!」と思われるかもしれませんが当時私は小学3年生。そんなの知ってるわけありません。
結局「ふーん。このレンタルサーバーだとできないんだ…」と諦めました。
それから約10年が経ち…
色々あって自分のサイトにreCAPTCHAを実装する機会がありまして…
その時にふとこのことを思い出しました。
そこで、「今の自分ならjavascriptだけでreCAPTCHAを実装できるのでは?」と思ってやってみました。
(もちろん設置できてもほぼ意味がないのはわかっています。ロマンです。ロマン。)

##で、どうなったのよ
完成したプログラムの実装の仕方のリンクはこちらです。
正直実用性は皆無です。
recaptchaが認証されていたらsuccessというアラートが出てフォームが送信されます。
認証されていなかったり、トークンが不正ならfaildというアラートが出ます。
わかる人は見たらすぐにわかると思うのですが、__formに"return false;"をつけている__んですよ。
このせいでjavascriptでsubmitしても思うように動いてくれなかったので新しくform要素を作って中身をコピーして送信するという物凄くめんどくさいことをやっているわけですね…
完全に私の力不足です。
もし改善方法がわかる方がいたら教えてください…

##とりあえず実装方法教えてくれない?

以下readmeに記載した項目です。

readme.md
recaptchajs

javascriptだけでrecaptcha(v2)の認証を行えるjsファイルです

使用例

<script src="//code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script src="https://lovetwice1012.github.io/recaptcha.js"></script>
<form method="post" enctype="multipart/form-data" id="recapchajs" onsubmit="return false;">
<div class="g-recaptcha" data-sitekey="your site key"></div>
<input id="grecaptchakey" type="hidden" value="your secret api key"></input>
<input type="submit"></input>
</form>

実装手順

htmlファイルに以下のスクリプトタグを挿入し、動作に必要なファイルを読み込んでください。

<script src="//code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script src="https://lovetwice1012.github.io/recaptcha.js"></script>

recaptchaを設置したフォームタグに、「id="recapchajs" onsubmit="return false;"」をつけてください。
※idは変更不可です。(今後変更に対応する可能性があります。)

手順2で指定したコードをつけたフォームタグの終了タグの前に、「<input id="grecaptchakey" type="hidden" value="your secret api key"></input>」を挿入してください。
※「your secret api key」はrecaptchaのコンソールで取得できるシークレットキーに置き換えてください。
最後に、recaptchaを表示したい場所に、「<div class="g-recaptcha" data-sitekey="your site key"></div>」を貼り付けてください。

これで設置作業は終了です。

なんてわかりにくくてめんどくさいんでしょう!

##で、ソースコードは?
これです。クソコード極めちゃってます。
もっといいやり方があると思うんですけどね…

$(function () {
  //フォームが送信されたら…
  $('#recapchajs').submit(function () {
    var flag = 0;
    //認証キーの確認
    var grecaptcharesponse = grecaptcha.getResponse();
    //確認する時に必要なシークレットキーを取得
    var secretAPIkey = $('#grecaptchakey').val();
    $.post("https://script.google.com/macros/s/AKfycbyC-ANdo97T-1V3c4rZ1EAGkxOF0VukbLXa7Og4-mcUW6mmhvM/exec", JSON.stringify({
      'secret': secretAPIkey,
      'response': grecaptcharesponse,
    }), function (data) {
      //上のAPIはreCAPTCHAの認証APIのレスポンスをそのまま返すようにしてるので、データを受信したらphpで受信する時と同じようにチェックする。
      data = JSON.parse(data);
      if (data.success) {
        alert("success");
        //form要素を追加して内容をコピーする。
        let f = document.createElement('form');
        f.method = 'post';
        f.action = document.getElementById("recapchajs").action;
        var innerHTML = "";
        for (const element of document.getElementById("recapchajs").elements) {
          innerHTML = innerHTML + "<input type=\"hidden\" name=\"" + element.name + "\" id=\"" + element.id + "\" + class=\"" + element.id + "\" value=\"" + element.value + "\" />";
        }
        f.innerHTML = innerHTML
        document.body.append(f);
        f.submit();
      } else {
        //認証していない、もしくは無効
        alert("faild");
      }
    }).fail(function (jqXHR, textStatus, errorThrown) {
      //エラーが起きたらその旨を伝える
      alert("error");
    });
  });
});

こんな実用性皆無の自己満のプログラムを使う人がいるとは思えませんがこういうアホなことやるバカもいるんだなぁと思っていただけたら嬉しいです。
では〜

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?