LoginSignup
6
7

More than 5 years have passed since last update.

GoogleAppEngineを使ってGithubPagesでreCAPTCHAを導入する

Posted at

前書き

特に意味はないけれどメールフォームを設置してみたかったので、
GoogleAppEngineでAPI作って、GihubPagesのポートフォリオに設置してみました

準備

まず、reCAPTCHAに登録する必要があります
reCAPTCAの画面を開いて
無題.png
Labelに適当な名前を入れて、Domainsに一行ごとにreCAPTCHAを利用するドメインを入れます(エイリアス用のドメインなど)
そしてRegisterをクリック

GithubPages側の記述

ふつうに<form>を書いてjsを貼り付けるだけです
さっき登録したあとに表示されたページの
2.png
Adding reCAPTCHA to your siteの中のStep 1: client-side integration<script src='https://www.google.com/recaptcha/api.js'></script>
をheadタグ内に、<div class="g-recaptcha" data-sitekey="~~~"></div>

内にコピペします
そして、POSTでGoogleAppEngine側をたたくように<form method="POST" action="~~GoogleAppEngineにつくるAPIのURL~~">と書きます
form内のそれぞれの入力箇所にname属性がついていることを確認します(ないとAPI側で受け取れません)

GoogleAppEngine側の記述

まず、ルーティングを適当に設定して、POSTを受け取り、その中のデータを取り出します
3.png
そうしたら、https://www.google.com/recaptcha/api/siteverifysecret さっきの登録したあとのページのStep2の中のsecret,response POSTで受け取ったg-recaptcha-responseをつけてPOSTします
そうすると、有効かどうかの結果が返ってきます(ex. {"success": true},{"success": false, "error-codes": [~]})
(GETでもできるみたいです ex.https://www.google.com/recaptcha/api/siteverify?secret=~&g-recaptcha-response=~)
これで有効かどうか受け取れたので、その結果を返すならページにパラメータつけてリダイレクトなどしてGithubPages側でページを書き換えるなどできます

ソース

自分はreCAPTCHAのあとで自分にメールを送りつけています(メールフォームなので…)
GoogleAppEngine側はGo、GitHubPages側はhaml(MaterialDesignLite使用)で書いています

GoogleAppEngine側

ルーティングの部分などは省略します
Goですが、おそらくほかの言語でもおんなじ感じでかけると思います

mainMail.go
package s4naxyz

import(
  "fmt"
  "net/http"
  "io/ioutil"
  "encoding/json"
  "google.golang.org/appengine"
  "google.golang.org/appengine/log"
  "google.golang.org/appengine/urlfetch"
  "google.golang.org/appengine/mail"
)

const secretkey = "~~~~secret~~~~"

type googleResponse struct {
    Success bool `json:success`
    ErrorCodes []string `json:error-codes`
}

func mailSendHandler(w http.ResponseWriter, r *http.Request) {
    ctx := appengine.NewContext(r)
    r.ParseForm()
    if r.Form.Get("g-recaptcha-response") == "" {
        log.Errorf(ctx, "Couldnt send email<recaptcha response error>")
        fmt.Fprint(w, "{error: true, message: \"recaptcha response error\"}")
        return
    }
    client := urlfetch.Client(ctx)
    res, err := client.Get("https://www.google.com/recaptcha/api/siteverify?secret="+secretkey+"&response="+r.Form.Get("g-recaptcha-response"))
    if err != nil {
        log.Errorf(ctx, "Couldnt send email<http getting error>: %v", err)
        fmt.Fprint(w, "{error: true, message: \"http getting error\"}")
        return
    }
    defer res.Body.Close()

    resByte, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Errorf(ctx, "Couldnt send email<body transforming error>: %v", err)
        fmt.Fprint(w, "{error: true, message: \"body transforming error\"}")
        return
    }

    parsed := googleResponse{}
    err = json.Unmarshal(resByte, &parsed)
    if err != nil {
        log.Errorf(ctx, "Couldnt send email<json parsing error>: %v", err)
        fmt.Fprint(w, "{error: true, message: \"json parsing error\"}")
        return
    }
    if !parsed.Success {
        log.Errorf(ctx, "Couldnt send email<recaptcha authorize error>")
        fmt.Fprint(w, "{error: true, message: \"recaptcha authorize error\"}")
        return
    }

    msg := &mail.Message{
        Sender: "api.4na.xyz <~~~GMailのアドレス~~~>",
        To: []string{"~~~普段使いのアドレス~~~"},
        Subject: r.Form.Get("title"),
        Body: "From: "+r.Form.Get("name")+" ("+r.Form.Get("email")+")\n----------\nMessage:\n"+r.Form.Get("message"),
    }
    if err := mail.Send(ctx, msg); err != nil {
        log.Errorf(ctx, "Couldnt send email<mail sending error>: %v", err)
        fmt.Fprint(w, "{error: true, message: \"mail sending error\"}}")
        return
    }
    w.Header().Set("Content-Type", "text/json")
    w.Header().Set("Access-Control-Allow-Origin", "*")

    //fmt.Fprint(w, "{error: false}")

    http.Redirect(w, r, "https://s.4na.xyz/contact/", 301)
}

fmt.Fprintしてリダイレクトみたいなことになってますが、
まだ作り途中なので…

GithubPages側

関連個所のみ抜粋で

index.haml
  #form.mdl-cell.mdl-cell--8-col
    .mdl-card.mdl-shadow--3dp
      .mdl-card__title
        %h2.h4.mdl-card__title-text Contact
      .mdl-card__supporting-text
        %form#form-main{method: "POST", action: "https://api.4na.xyz/mail/send"}
          .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label
            %input.mdl-textfield__input#name{name: "name", type: "text", required: true}
            %label.mdl-textfield__label{for: "name"} Name
          %br
          .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label
            %input.mdl-textfield__input#email{name: "email", type: "email", required: true}
            %label.mdl-textfield__label{for: "email"} Email Address
          %br
          .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label
            %input.mdl-textfield__input#title{name: "title", type: "text", required: true}
            %label.mdl-textfield__label{for: "title"} Title
          %br
          .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label
            %textarea.mdl-textfield__input#message{name: "message", type: "text", rows: "5", required: true}
            %label.mdl-textfield__label{for: "message"} Message
          %br
          .g-recaptcha{"data-sitekey": "~~~sitekey~~~"}
          %input#submit.mdl-button.mdl-js-button.mdl-button--raised.mdl-button--colored.mdl-js-ripple-effect{type: "submit"}
  %script{type: "text/javascript", src: "https://www.google.com/recaptcha/api.js?hl=ja", defer: true, async: true}

関連情報

reCAPTCHA

GithubPages

GoogleAppEngine

6
7
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
6
7